paskia 0.8.1__py3-none-any.whl → 0.9.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. paskia/_version.py +2 -2
  2. paskia/authsession.py +14 -27
  3. paskia/bootstrap.py +31 -103
  4. paskia/db/__init__.py +25 -51
  5. paskia/db/background.py +17 -37
  6. paskia/db/jsonl.py +168 -6
  7. paskia/db/migrations.py +34 -0
  8. paskia/db/operations.py +400 -723
  9. paskia/db/structs.py +214 -90
  10. paskia/fastapi/__main__.py +24 -28
  11. paskia/fastapi/admin.py +101 -160
  12. paskia/fastapi/api.py +47 -83
  13. paskia/fastapi/mainapp.py +13 -6
  14. paskia/fastapi/remote.py +16 -39
  15. paskia/fastapi/reset.py +27 -17
  16. paskia/fastapi/session.py +2 -2
  17. paskia/fastapi/user.py +21 -27
  18. paskia/fastapi/ws.py +27 -62
  19. paskia/fastapi/wschat.py +62 -0
  20. paskia/frontend-build/auth/admin/index.html +5 -5
  21. paskia/frontend-build/auth/assets/{AccessDenied-Bc249ASC.css → AccessDenied-DPkUS8LZ.css} +1 -1
  22. paskia/frontend-build/auth/assets/AccessDenied-Fmeb6EtF.js +8 -0
  23. paskia/frontend-build/auth/assets/{RestrictedAuth-DgdJyscT.css → RestrictedAuth-CvR33_Z0.css} +1 -1
  24. paskia/frontend-build/auth/assets/RestrictedAuth-DsJXicIw.js +1 -0
  25. paskia/frontend-build/auth/assets/{_plugin-vue_export-helper-rKFEraYH.js → _plugin-vue_export-helper-nhjnO_bd.js} +1 -1
  26. paskia/frontend-build/auth/assets/admin-CPE1pLMm.js +1 -0
  27. paskia/frontend-build/auth/assets/{admin-BeNu48FR.css → admin-DzzjSg72.css} +1 -1
  28. paskia/frontend-build/auth/assets/{auth-BKX7shEe.css → auth-C7k64Wad.css} +1 -1
  29. paskia/frontend-build/auth/assets/auth-YIZvPlW_.js +1 -0
  30. paskia/frontend-build/auth/assets/{forward-Dzg-aE1C.js → forward-DmqVHZ7e.js} +1 -1
  31. paskia/frontend-build/auth/assets/reset-Chtv69AT.css +1 -0
  32. paskia/frontend-build/auth/assets/reset-s20PATTN.js +1 -0
  33. paskia/frontend-build/auth/assets/{restricted-C0IQufuH.js → restricted-D3AJx3_6.js} +1 -1
  34. paskia/frontend-build/auth/index.html +5 -5
  35. paskia/frontend-build/auth/restricted/index.html +4 -4
  36. paskia/frontend-build/int/forward/index.html +4 -4
  37. paskia/frontend-build/int/reset/index.html +3 -3
  38. paskia/globals.py +2 -2
  39. paskia/migrate/__init__.py +62 -55
  40. paskia/migrate/sql.py +72 -22
  41. paskia/remoteauth.py +1 -2
  42. paskia/sansio.py +6 -12
  43. {paskia-0.8.1.dist-info → paskia-0.9.0.dist-info}/METADATA +1 -1
  44. paskia-0.9.0.dist-info/RECORD +57 -0
  45. paskia/frontend-build/auth/assets/AccessDenied-aTdCvz9k.js +0 -8
  46. paskia/frontend-build/auth/assets/RestrictedAuth-BLMK7-nL.js +0 -1
  47. paskia/frontend-build/auth/assets/admin-tVs8oyLv.js +0 -1
  48. paskia/frontend-build/auth/assets/auth-Dk3q4pNS.js +0 -1
  49. paskia/frontend-build/auth/assets/reset-BWF4cWKR.css +0 -1
  50. paskia/frontend-build/auth/assets/reset-C_Td1_jn.js +0 -1
  51. paskia-0.8.1.dist-info/RECORD +0 -55
  52. {paskia-0.8.1.dist-info → paskia-0.9.0.dist-info}/WHEEL +0 -0
  53. {paskia-0.8.1.dist-info → paskia-0.9.0.dist-info}/entry_points.txt +0 -0
@@ -1,8 +0,0 @@
1
- import{M as At,r as F,N as Rt,O as Yt,P as le,Q as Tt,R as Qt,S as Gt,T as Wt,n as ze,U as Zt,c as x,w as He,V as Xt,W as en,H as Q,m as tn,X as nn,Y as on,b as R,f as L,z as U,d as T,e as v,t as D,g as se,_ as Y,F as oe,i as ce,B as z,D as Mt,l as de,Z as Nt,$ as Pt,a0 as Dt,a1 as Lt,o as qt,a2 as rn,a as Ft,C as sn,k as xe,h as an,a3 as un,L as ln,x as cn}from"./_plugin-vue_export-helper-rKFEraYH.js";import{f as G,h as ae,g as We}from"./helpers-DzjFIx78.js";let Ut;const fe=e=>Ut=e,Kt=Symbol();function Oe(e){return e&&typeof e=="object"&&Object.prototype.toString.call(e)==="[object Object]"&&typeof e.toJSON!="function"}var re;(function(e){e.direct="direct",e.patchObject="patch object",e.patchFunction="patch function"})(re||(re={}));function br(){const e=At(!0),s=e.run(()=>F({}));let r=[],t=[];const n=Rt({install(o){fe(n),n._a=o,o.provide(Kt,n),o.config.globalProperties.$pinia=n,t.forEach(i=>r.push(i)),t=[]},use(o){return this._a?r.push(o):t.push(o),this},_p:r,_a:null,_e:e,_s:new Map,state:s});return n}const Vt=()=>{};function Ze(e,s,r,t=Vt){e.add(s);const n=()=>{e.delete(s)&&t()};return!r&&Gt()&&Wt(n),n}function ee(e,...s){e.forEach(r=>{r(...s)})}const dn=e=>e(),Xe=Symbol(),pe=Symbol();function je(e,s){e instanceof Map&&s instanceof Map?s.forEach((r,t)=>e.set(t,r)):e instanceof Set&&s instanceof Set&&s.forEach(e.add,e);for(const r in s){if(!s.hasOwnProperty(r))continue;const t=s[r],n=e[r];Oe(n)&&Oe(t)&&e.hasOwnProperty(r)&&!le(t)&&!Tt(t)?e[r]=je(n,t):e[r]=t}return e}const fn=Symbol();function hn(e){return!Oe(e)||!Object.prototype.hasOwnProperty.call(e,fn)}const{assign:J}=Object;function gn(e){return!!(le(e)&&e.effect)}function mn(e,s,r,t){const{state:n,actions:o,getters:i}=s,a=r.state.value[e];let u;function l(){a||(r.state.value[e]=n?n():{});const f=Zt(r.state.value[e]);return J(f,o,Object.keys(i||{}).reduce((w,b)=>(w[b]=Rt(x(()=>{fe(r);const h=r._s.get(e);return i[b].call(h,h)})),w),{}))}return u=Ht(e,l,s,r,t,!0),u}function Ht(e,s,r={},t,n,o){let i;const a=J({actions:{}},r),u={deep:!0};let l,f,w=new Set,b=new Set,h;const d=t.state.value[e];!o&&!d&&(t.state.value[e]={}),F({});let g;function N(y){let m;l=f=!1,typeof y=="function"?(y(t.state.value[e]),m={type:re.patchFunction,storeId:e,events:h}):(je(t.state.value[e],y),m={type:re.patchObject,payload:y,storeId:e,events:h});const _=g=Symbol();ze().then(()=>{g===_&&(l=!0)}),f=!0,ee(w,m,t.state.value[e])}const A=o?function(){const{state:m}=r,_=m?m():{};this.$patch(E=>{J(E,_)})}:Vt;function P(){i.stop(),w.clear(),b.clear(),t._s.delete(e)}const c=(y,m="")=>{if(Xe in y)return y[pe]=m,y;const _=function(){fe(t);const E=Array.from(arguments),k=new Set,B=new Set;function M(q){k.add(q)}function V(q){B.add(q)}ee(b,{args:E,name:_[pe],store:I,after:M,onError:V});let K;try{K=y.apply(this&&this.$id===e?this:I,E)}catch(q){throw ee(B,q),q}return K instanceof Promise?K.then(q=>(ee(k,q),q)).catch(q=>(ee(B,q),Promise.reject(q))):(ee(k,K),K)};return _[Xe]=!0,_[pe]=m,_},S={_p:t,$id:e,$onAction:Ze.bind(null,b),$patch:N,$reset:A,$subscribe(y,m={}){const _=Ze(w,y,m.detached,()=>E()),E=i.run(()=>He(()=>t.state.value[e],k=>{(m.flush==="sync"?f:l)&&y({storeId:e,type:re.direct,events:h},k)},J({},u,m)));return _},$dispose:P},I=Yt(S);t._s.set(e,I);const p=(t._a&&t._a.runWithContext||dn)(()=>t._e.run(()=>(i=At()).run(()=>s({action:c}))));for(const y in p){const m=p[y];if(le(m)&&!gn(m)||Tt(m))o||(d&&hn(m)&&(le(m)?m.value=d[y]:je(m,d[y])),t.state.value[e][y]=m);else if(typeof m=="function"){const _=c(m,y);p[y]=_,a.actions[y]=m}}return J(I,p),J(Qt(I),p),Object.defineProperty(I,"$state",{get:()=>t.state.value[e],set:y=>{N(m=>{J(m,y)})}}),t._p.forEach(y=>{J(I,i.run(()=>y({store:I,app:t._a,pinia:t,options:a})))}),d&&o&&r.hydrate&&r.hydrate(I.$state,d),l=!0,f=!0,I}function yn(e,s,r){let t;const n=typeof s=="function";t=n?r:s;function o(i,a){const u=en();return i=i||(u?Xt(Kt,null):null),i&&fe(i),i=Ut,i._s.has(e)||(n?Ht(e,s,t,i):mn(e,t,i)),i._s.get(e)}return o.$id=e,o}const $e=yn("auth",{state:()=>({userInfo:null,isLoading:!1,settings:null,currentView:"login",status:{message:"",type:"info",show:!1}}),getters:{},actions:{setLoading(e){this.isLoading=!!e},showMessage(e,s="info",r=null){const t=r??(s==="error"?5e3:3e3);this.status={message:e,type:s,show:!0},t>0&&setTimeout(()=>{this.status.show=!1},t)},async setSessionCookie(e){if(!e?.session_token)throw console.error("setSessionCookie called with missing session_token:",e),new Error("Authentication response missing session_token");return await Q("/auth/api/set-session",{method:"POST",headers:{Authorization:`Bearer ${e.session_token}`}})},async register(){this.isLoading=!0;try{const e=await on();return await this.setSessionCookie(e),await this.loadUserInfo(),this.selectView(),e}finally{this.isLoading=!1}},async authenticate(){this.isLoading=!0;try{const e=await nn();return await this.setSessionCookie(e),await this.loadUserInfo(),this.selectView(),e}finally{this.isLoading=!1}},selectView(){this.userInfo?this.currentView="profile":this.currentView="login"},async loadSettings(){this.settings=await tn()},async loadUserInfo(){try{this.userInfo=await Q("/auth/api/user-info",{method:"POST"}),console.log("User info loaded:",this.userInfo)}catch(e){throw e.status===401||e.status===403?console.log("Authentication required:",e.message):this.showMessage(e.message||"Failed to load user info","error",5e3),e}},async deleteCredential(e){await Q(`/auth/api/user/credential/${e}`,{method:"DELETE"}),await this.loadUserInfo()},async terminateSession(e){try{if((await Q(`/auth/api/user/session/${e}`,{method:"DELETE"}))?.current_session_terminated){sessionStorage.clear(),location.reload();return}await this.loadUserInfo(),this.showMessage("Session terminated","success",2500)}catch(s){throw console.error("Terminate session error:",s),s}},async logout(){try{await Q("/auth/api/logout",{method:"POST"}),sessionStorage.clear(),location.reload()}catch(e){console.error("Logout error:",e),e.status!==401&&e.status!==403&&this.showMessage(e.message,"error")}},async logoutEverywhere(){try{await Q("/auth/api/user/logout-all",{method:"POST"}),sessionStorage.clear(),location.reload()}catch(e){console.error("Logout-all error:",e),e.status!==401&&e.status!==403&&this.showMessage(e.message,"error")}}}}),pn={key:0,class:"global-status",style:{display:"block"}},vr={__name:"StatusMessage",setup(e){const s=$e();return(r,t)=>U(s).status.show?(T(),R("div",pn,[v("div",{class:se(["status",U(s).status.type])},D(U(s).status.message),3)])):L("",!0)}},wn=["href"],bn={key:0,class:"sep"},vn={__name:"Breadcrumbs",props:{entries:{type:Array,default:()=>[]},showHome:{type:Boolean,default:!0},homeHref:{type:String,default:"/"}},setup(e,{expose:s}){const r=e,t=F(null),n=x(()=>r.showHome&&r.entries.length>0&&r.entries[0].href===r.homeHref?[{label:"🏠 "+r.entries[0].label,href:r.homeHref},...r.entries.slice(1)]:[...r.showHome?[{label:"🏠",href:r.homeHref}]:[],...r.entries]),o=x(()=>{const l=window.location.hash||window.location.pathname;for(let f=n.value.length-1;f>=0;f--){const w=n.value[f].href;if(w===l||w&&l.startsWith(w))return f}return n.value.length-1});function i(l){if(l.target===t.value){const f=t.value.querySelectorAll("a"),w=Math.min(o.value,f.length-1);f[w]&&f[w].focus()}}function a(l){const f=z(l);f&&(f==="left"||f==="right")&&(l.preventDefault(),Mt(t.value,l.target,f,{itemSelector:"a"}))}function u(){const l=t.value?.querySelectorAll("a");if(l?.length){const f=Math.min(o.value,l.length-1);l[f]?.focus()}}return s({focusCurrent:u}),(l,f)=>n.value.length>1?(T(),R("nav",{key:0,ref_key:"navRef",ref:t,class:"breadcrumbs","aria-label":"Breadcrumb",tabindex:"0",onFocusin:i,onKeydown:a},[v("ol",null,[(T(!0),R(oe,null,ce(n.value,(w,b)=>(T(),R("li",{key:b},[v("a",{href:w.href,tabindex:"-1"},D(w.label),9,wn),b<n.value.length-1?(T(),R("span",bn," — ")):L("",!0)]))),128))])],544)):L("",!0)}},Cr=Y(vn,[["__scopeId","data-v-6344dbb8"]]),Cn={key:0},Sn={key:1},_n=["onFocusin","onKeydown"],En={class:"item-top"},kn={class:"item-icon"},Bn=["src","alt"],In={key:1,class:"auth-emoji"},An={class:"item-title"},Rn={class:"item-actions"},Tn={key:0,class:"badge badge-current"},Mn={key:1,class:"badge badge-current"},Nn={key:2,class:"badge badge-current"},Pn=["onClick","disabled","title"],Dn={class:"item-details"},Ln={class:"credential-dates"},qn={class:"date-value"},Fn={class:"date-value"},Un={class:"date-value"},Sr={__name:"CredentialList",props:{credentials:{type:Array,default:()=>[]},aaguidInfo:{type:Object,default:()=>({})},loading:{type:Boolean,default:!1},allowDelete:{type:Boolean,default:!1},hoveredCredentialUuid:{type:String,default:null},hoveredSessionCredentialUuid:{type:String,default:null},navigationDisabled:{type:Boolean,default:!1}},emits:["delete","credentialHover","navigate-out"],setup(e,{emit:s}){const r=e,t=s,n=h=>{t("credentialHover",h)},o=h=>{h.currentTarget.contains(h.relatedTarget)||t("credentialHover",null)},i=h=>{h.currentTarget.matches(":focus")||(h.currentTarget.focus(),h.stopPropagation())},a=(h,d)=>{Pt(h,()=>{r.allowDelete&&!d.is_current_session&&t("delete",d)})},u=h=>{if(r.navigationDisabled)return;const d=h.currentTarget;if(h.target===d){const g=d.querySelector(".credential-item");g&&g.focus()}},l=h=>{r.navigationDisabled||Dt(h,d=>t("navigate-out",d))},f=(h,d)=>{if(a(h,d),h.defaultPrevented||r.navigationDisabled)return;const g=z(h);if(g){h.preventDefault();const N=h.currentTarget.closest(".credential-list");Nt(N,h.currentTarget,g,{itemSelector:".credential-item"})==="boundary"&&t("navigate-out",g)}},w=h=>{const d=r.aaguidInfo?.[h.aaguid];return d?d.name:"Unknown Authenticator"},b=h=>{const d=r.aaguidInfo?.[h.aaguid];if(!d)return null;const N=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"icon_dark":"icon_light";return d[N]||null};return(h,d)=>(T(),R("div",{class:"credential-list",tabindex:"0",onFocusin:u,onKeydown:l},[e.loading?(T(),R("div",Cn,[...d[2]||(d[2]=[v("p",null,"Loading credentials...",-1)])])):e.credentials?.length?(T(!0),R(oe,{key:2},ce(e.credentials,g=>(T(),R("div",{key:g.credential_uuid,class:se(["credential-item",{"current-session":g.is_current_session&&!e.hoveredCredentialUuid&&!e.hoveredSessionCredentialUuid,"is-hovered":e.hoveredCredentialUuid===g.credential_uuid,"is-linked-session":e.hoveredSessionCredentialUuid===g.credential_uuid}]),tabindex:"-1",onMousedown:d[0]||(d[0]=de(()=>{},["prevent"])),onClickCapture:i,onFocusin:N=>n(g.credential_uuid),onFocusout:d[1]||(d[1]=N=>o(N)),onKeydown:N=>f(N,g)},[v("div",En,[v("div",kn,[b(g)?(T(),R("img",{key:0,src:b(g),alt:w(g),class:"auth-icon",width:"32",height:"32"},null,8,Bn)):(T(),R("span",In,"🔑"))]),v("h4",An,D(w(g)),1),v("div",Rn,[g.is_current_session&&!e.hoveredCredentialUuid&&!e.hoveredSessionCredentialUuid?(T(),R("span",Tn,"Current")):e.hoveredCredentialUuid===g.credential_uuid?(T(),R("span",Mn,"Selected")):e.hoveredSessionCredentialUuid===g.credential_uuid?(T(),R("span",Nn,"Linked")):L("",!0),e.allowDelete?(T(),R("button",{key:3,onClick:N=>h.$emit("delete",g),class:"btn-card-delete",disabled:g.is_current_session,title:g.is_current_session?"Cannot delete current session credential":"Delete passkey and terminate any linked sessions.",tabindex:"-1"},"❌",8,Pn)):L("",!0)])]),v("div",Dn,[v("div",Ln,[d[4]||(d[4]=v("span",{class:"date-label"},"Created:",-1)),v("span",qn,D(U(G)(g.created_at)),1),d[5]||(d[5]=v("span",{class:"date-label"},"Last used:",-1)),v("span",Fn,D(U(G)(g.last_used)),1),d[6]||(d[6]=v("span",{class:"date-label"},"Last verified:",-1)),v("span",Un,D(U(G)(g.last_verified)),1)])])],42,_n))),128)):(T(),R("div",Sn,[...d[3]||(d[3]=[v("p",null,"No passkeys found.",-1)])]))],32))}},Kn={class:"user-name-heading"},Vn={class:"user-name-row"},Hn=["title"],On={key:0,class:"org-role-sub"},jn={key:0,class:"org-line"},zn={key:1,class:"role-line"},xn={class:"user-details"},$n={class:"date-value"},Jn={class:"date-value"},Yn={class:"date-value"},Qn={key:1,class:"user-info-extra"},Gn={__name:"UserBasicInfo",props:{name:{type:String,required:!0},visits:{type:[Number,String],default:0},createdAt:{type:[String,Number,Date],default:null},lastSeen:{type:[String,Number,Date],default:null},updateEndpoint:{type:String,default:null},canEdit:{type:Boolean,default:!0},loading:{type:Boolean,default:!1},orgDisplayName:{type:String,default:""},roleName:{type:String,default:""}},emits:["saved","editName"],setup(e,{emit:s}){const r=e,t=s;$e();const n=x(()=>!!r.name);return(o,i)=>n.value?(T(),R("div",{key:0,class:se(["user-info",{"has-extra":o.$slots.default}])},[v("h3",Kn,[i[1]||(i[1]=v("span",{class:"icon"},"👤",-1)),v("span",Vn,[v("span",{class:"display-name",title:e.name},D(e.name),9,Hn),e.canEdit&&e.updateEndpoint?(T(),R("button",{key:0,class:"mini-btn",onClick:i[0]||(i[0]=a=>t("editName")),title:"Edit name"},"✏️")):L("",!0)])]),e.orgDisplayName||e.roleName?(T(),R("div",On,[e.orgDisplayName?(T(),R("div",jn,D(e.orgDisplayName),1)):L("",!0),e.roleName?(T(),R("div",zn,D(e.roleName),1)):L("",!0)])):L("",!0),v("div",xn,[i[2]||(i[2]=v("span",{class:"date-label"},[v("strong",null,"Visits:")],-1)),v("span",$n,D(e.visits||0),1),i[3]||(i[3]=v("span",{class:"date-label"},[v("strong",null,"Registered:")],-1)),v("span",Jn,D(U(G)(e.createdAt)),1),i[4]||(i[4]=v("span",{class:"date-label"},[v("strong",null,"Last seen:")],-1)),v("span",Yn,D(U(G)(e.lastSeen)),1)]),o.$slots.default?(T(),R("div",Qn,[Lt(o.$slots,"default",{},void 0)])):L("",!0)],2)):L("",!0)}},_r=Y(Gn,[["__scopeId","data-v-ce373d6c"]]),Wn={__name:"Modal",props:{focusFallback:{type:[HTMLElement,Object],default:null},focusIndex:{type:Number,default:-1},focusSiblingSelector:{type:String,default:""}},emits:["close"],setup(e){const s=e,r=F(null),t=F(null),n=()=>{const i=t.value;if(!i)return;if(document.body.contains(i)&&!i.disabled){i.focus();return}if(s.focusSiblingSelector&&s.focusIndex>=0){const u=[s.focusFallback?.$el||s.focusFallback,i.closest("[data-nav-group]"),i.parentElement?.closest("section"),document.querySelector(".view-root")].filter(Boolean);for(const l of u){if(!l)continue;const f=l.querySelectorAll(s.focusSiblingSelector);if(f.length>0){const w=Math.min(s.focusIndex,f.length-1),b=f[w];if(b&&!b.disabled){b.focus();return}}}}const a=s.focusFallback?.$el||s.focusFallback;if(a&&document.body.contains(a)){const u=a.querySelector?.('button:not([disabled]), a, [tabindex="0"]')||a;if(u?.focus){u.focus();return}}},o=i=>{const a=z(i);if(!a)return;const u=i.target,l=u.closest(".modal-actions");if(l&&(a==="left"||a==="right"))i.preventDefault(),Mt(l,u,a,{itemSelector:"button"});else if(a==="up"&&l){i.preventDefault();const w=(l.closest("form")||l.closest(".modal-form"))?.querySelectorAll("input, textarea, select, button:not(.modal-actions button)");w&&w.length>0&&w[w.length-1].focus()}else if(a==="down"&&!l){const f=u.closest("form")||u.closest(".modal-form");if(f){i.preventDefault();const w=f.querySelector(".modal-actions");w&&sn(w,{primarySelector:".btn-primary",itemSelector:"button"})}}};return qt(()=>{t.value=document.activeElement,ze(()=>{if(r.value){r.value.showModal();const i=r.value.querySelector(".modal-actions .btn-primary");i&&i.setAttribute("data-nav-primary",""),rn(r.value)}})}),Ft(()=>{n()}),(i,a)=>(T(),R("dialog",{ref_key:"dialog",ref:r,onClose:a[0]||(a[0]=u=>i.$emit("close")),onKeydown:o},[Lt(i.$slots,"default",{},void 0)],544))}},Er=Y(Wn,[["__scopeId","data-v-2ebcbb0a"]]),Zn={class:"name-edit-form"},Xn=["for"],eo=["id","type","placeholder","disabled"],to={key:0,class:"error small"},no=["disabled"],oo=["disabled"],ro={__name:"NameEditForm",props:{modelValue:{type:String,default:""},label:{type:String,default:"Name"},placeholder:{type:String,default:""},submitText:{type:String,default:"Save"},cancelText:{type:String,default:"Cancel"},busy:{type:Boolean,default:!1},error:{type:String,default:""},autoFocus:{type:Boolean,default:!0},autoSelect:{type:Boolean,default:!0},inputId:{type:String,default:null},inputType:{type:String,default:"text"}},emits:["update:modelValue","cancel"],setup(e,{emit:s}){const r=e,t=s,n=F(null),o=`name-edit-${Math.random().toString(36).slice(2,10)}`,i=x({get:()=>r.modelValue,set:f=>t("update:modelValue",f)}),a=x(()=>r.inputId||o),u=f=>{if(z(f)==="up"){f.preventDefault(),n.value?.focus();return}};function l(){t("cancel")}return(f,w)=>(T(),R("div",Zn,[v("label",{for:a.value},[xe(D(e.label)+" ",1),an(v("input",{id:a.value,ref_key:"inputRef",ref:n,type:e.inputType,placeholder:e.placeholder,"onUpdate:modelValue":w[0]||(w[0]=b=>i.value=b),disabled:e.busy,required:""},null,8,eo),[[un,i.value]])],8,Xn),e.error?(T(),R("div",to,D(e.error),1)):L("",!0),v("div",{class:"modal-actions",onKeydown:u},[v("button",{type:"button",class:"btn-secondary",onClick:l,disabled:e.busy},D(e.cancelText),9,no),v("button",{type:"submit",class:"btn-primary",disabled:e.busy,"data-nav-primary":""},D(e.submitText),9,oo)],32)]))}},kr=Y(ro,[["__scopeId","data-v-b73321cf"]]),so={class:"section-block","data-component":"session-list-section"},io={class:"section-header"},ao={class:"section-description"},uo={class:"section-body"},lo=["onKeydown"],co=["href"],fo={class:"session-list"},ho=["onFocusin","onKeydown"],go={class:"item-top"},mo={class:"item-title"},yo={class:"item-actions"},po={key:0,class:"badge badge-current"},wo={key:1,class:"badge badge-current"},bo={key:2,class:"badge badge-current"},vo={key:3,class:"badge"},Co=["onClick","disabled","title"],So={class:"item-details"},_o={class:"session-dates"},Eo={class:"date-label"},ko=["onClick"],Bo={key:1,class:"empty-state"},Br={__name:"SessionList",props:{sessions:{type:Array,default:()=>[]},emptyMessage:{type:String,default:"You currently have no other active sessions."},sectionDescription:{type:String,default:"Review where you're signed in and end any sessions you no longer recognize."},terminatingSessions:{type:Object,default:()=>({})},hoveredCredentialUuid:{type:String,default:null},navigationDisabled:{type:Boolean,default:!1}},emits:["terminate","sessionHover","navigate-out"],setup(e,{emit:s}){const r=e,t=s,n=$e(),o=F(null),i=F(null),a=c=>{i.value=c,o.value=c.ip||null,t("sessionHover",c)},u=c=>{c.currentTarget.contains(c.relatedTarget)||(i.value=null,o.value=null,t("sessionHover",null))},l=c=>{c.currentTarget.matches(":focus")||(c.currentTarget.focus(),c.stopPropagation())},f=c=>!!r.terminatingSessions[c],w=(c,S)=>{const I=c.currentTarget,p=I.querySelector(".session-list")?.querySelectorAll(".session-item"),y=Array.from(document.querySelectorAll(".session-group")),m=y.indexOf(I);if(c.key==="Enter"&&c.target===I){S&&I.querySelector("a")?.click();return}if(r.navigationDisabled)return;const _=z(c);if(["down","right"].includes(_)&&c.target===I){c.preventDefault(),p?.[0]?.focus();return}if(["up","left"].includes(_)&&c.target===I){c.preventDefault(),m>0?y[m-1].focus():t("navigate-out","up");return}Dt(c,E=>t("navigate-out",E))},b=(c,S)=>{if(Pt(c,()=>{f(S.id)||t("terminate",S)}),c.defaultPrevented||r.navigationDisabled)return;const I=z(c);if(I){c.preventDefault();const C=c.currentTarget.closest(".session-group"),p=C.querySelector(".session-list");if(Nt(p,c.currentTarget,I,{itemSelector:".session-item"})==="boundary"){if(I==="left"||I==="up")C?.focus();else if(I==="down"||I==="right"){const m=Array.from(document.querySelectorAll(".session-group")),_=m.indexOf(C);_<m.length-1?m[_+1].focus():t("navigate-out","down")}}}c.key==="Escape"&&(c.preventDefault(),c.currentTarget.closest(".session-group")?.focus())},h=c=>`${c.includes(":")?"http":"https"}://${c}`,d=async c=>{if(c)try{await navigator.clipboard.writeText(c),n.showMessage("Full IP copied to clipboard!","success",2e3)}catch(S){console.error("Failed to copy IP:",S),n.showMessage("Failed to copy IP","error",3e3)}},g=c=>ae(c)??c,N=x(()=>{if(o.value)return ae(o.value);const c=r.sessions.find(S=>S.is_current);return c?ae(c.ip):null}),A=c=>N.value&&ae(c)===N.value,P=x(()=>{const c={};for(const p of r.sessions){const y=p.host||"";c[y]||(c[y]={sessions:[],isCurrentSite:!1}),c[y].sessions.push(p),p.is_current_host&&(c[y].isCurrentSite=!0)}for(const p in c)c[p].sessions.sort((y,m)=>new Date(m.last_renewed)-new Date(y.last_renewed));const S=new Intl.Collator(void 0,{numeric:!0,sensitivity:"base"}),I=Object.keys(c).sort(S.compare),C={};for(const p of I)C[p]=c[p];return C});return(c,S)=>(T(),R("section",so,[v("div",io,[S[2]||(S[2]=v("h2",null,"Active Sessions",-1)),v("p",ao,D(e.sectionDescription),1)]),v("div",uo,[v("div",null,[Array.isArray(e.sessions)&&e.sessions.length?(T(!0),R(oe,{key:0},ce(P.value,(I,C)=>(T(),R("div",{key:C,class:"session-group",tabindex:"0",onKeydown:p=>w(p,C)},[v("span",{class:se(["session-group-host",{"is-current-site":I.isCurrentSite}])},[S[3]||(S[3]=v("span",{class:"session-group-icon"},"🌐",-1)),C?(T(),R("a",{key:0,href:h(C),tabindex:"-1",target:"_blank",rel:"noopener noreferrer"},D(C),9,co)):(T(),R(oe,{key:1},[xe("Unbound host")],64))],2),v("div",fo,[(T(!0),R(oe,null,ce(I.sessions,p=>(T(),R("div",{key:p.id,class:se(["session-item",{"is-current":p.is_current&&!o.value&&!e.hoveredCredentialUuid,"is-hovered":i.value?.id===p.id,"is-linked-credential":e.hoveredCredentialUuid===p.credential_uuid}]),tabindex:"-1",onMousedown:S[0]||(S[0]=de(()=>{},["prevent"])),onClickCapture:l,onFocusin:y=>a(p),onFocusout:S[1]||(S[1]=y=>u(y)),onKeydown:y=>b(y,p)},[v("div",go,[v("h4",mo,D(p.user_agent),1),v("div",yo,[p.is_current&&!o.value&&!e.hoveredCredentialUuid?(T(),R("span",po,"Current")):i.value?.id===p.id?(T(),R("span",wo,"Selected")):e.hoveredCredentialUuid===p.credential_uuid?(T(),R("span",bo,"Linked")):!e.hoveredCredentialUuid&&A(p.ip)?(T(),R("span",vo,"Same IP")):L("",!0),v("button",{onClick:y=>c.$emit("terminate",p),class:"btn-card-delete",disabled:f(p.id),title:f(p.id)?"Terminating...":"Terminate session",tabindex:"-1"},"❌",8,Co)])]),v("div",So,[v("div",_o,[v("span",Eo,D(U(G)(p.last_renewed)),1),v("span",{class:"date-value",onClick:y=>d(p.ip),title:"Click to copy full IP"},D(g(p.ip)),9,ko)])])],42,ho))),128))])],40,lo))),128)):(T(),R("div",Bo,[v("p",null,D(e.emptyMessage),1)]))])])]))}};function Io(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var te={},we,et;function Ao(){return et||(et=1,we=function(){return typeof Promise=="function"&&Promise.prototype&&Promise.prototype.then}),we}var be={},$={},tt;function W(){if(tt)return $;tt=1;let e;const s=[0,26,44,70,100,134,172,196,242,292,346,404,466,532,581,655,733,815,901,991,1085,1156,1258,1364,1474,1588,1706,1828,1921,2051,2185,2323,2465,2611,2761,2876,3034,3196,3362,3532,3706];return $.getSymbolSize=function(t){if(!t)throw new Error('"version" cannot be null or undefined');if(t<1||t>40)throw new Error('"version" should be in range from 1 to 40');return t*4+17},$.getSymbolTotalCodewords=function(t){return s[t]},$.getBCHDigit=function(r){let t=0;for(;r!==0;)t++,r>>>=1;return t},$.setToSJISFunction=function(t){if(typeof t!="function")throw new Error('"toSJISFunc" is not a valid function.');e=t},$.isKanjiModeEnabled=function(){return typeof e<"u"},$.toSJIS=function(t){return e(t)},$}var ve={},nt;function Je(){return nt||(nt=1,(function(e){e.L={bit:1},e.M={bit:0},e.Q={bit:3},e.H={bit:2};function s(r){if(typeof r!="string")throw new Error("Param is not a string");switch(r.toLowerCase()){case"l":case"low":return e.L;case"m":case"medium":return e.M;case"q":case"quartile":return e.Q;case"h":case"high":return e.H;default:throw new Error("Unknown EC Level: "+r)}}e.isValid=function(t){return t&&typeof t.bit<"u"&&t.bit>=0&&t.bit<4},e.from=function(t,n){if(e.isValid(t))return t;try{return s(t)}catch{return n}}})(ve)),ve}var Ce,ot;function Ro(){if(ot)return Ce;ot=1;function e(){this.buffer=[],this.length=0}return e.prototype={get:function(s){const r=Math.floor(s/8);return(this.buffer[r]>>>7-s%8&1)===1},put:function(s,r){for(let t=0;t<r;t++)this.putBit((s>>>r-t-1&1)===1)},getLengthInBits:function(){return this.length},putBit:function(s){const r=Math.floor(this.length/8);this.buffer.length<=r&&this.buffer.push(0),s&&(this.buffer[r]|=128>>>this.length%8),this.length++}},Ce=e,Ce}var Se,rt;function To(){if(rt)return Se;rt=1;function e(s){if(!s||s<1)throw new Error("BitMatrix size must be defined and greater than 0");this.size=s,this.data=new Uint8Array(s*s),this.reservedBit=new Uint8Array(s*s)}return e.prototype.set=function(s,r,t,n){const o=s*this.size+r;this.data[o]=t,n&&(this.reservedBit[o]=!0)},e.prototype.get=function(s,r){return this.data[s*this.size+r]},e.prototype.xor=function(s,r,t){this.data[s*this.size+r]^=t},e.prototype.isReserved=function(s,r){return this.reservedBit[s*this.size+r]},Se=e,Se}var _e={},st;function Mo(){return st||(st=1,(function(e){const s=W().getSymbolSize;e.getRowColCoords=function(t){if(t===1)return[];const n=Math.floor(t/7)+2,o=s(t),i=o===145?26:Math.ceil((o-13)/(2*n-2))*2,a=[o-7];for(let u=1;u<n-1;u++)a[u]=a[u-1]-i;return a.push(6),a.reverse()},e.getPositions=function(t){const n=[],o=e.getRowColCoords(t),i=o.length;for(let a=0;a<i;a++)for(let u=0;u<i;u++)a===0&&u===0||a===0&&u===i-1||a===i-1&&u===0||n.push([o[a],o[u]]);return n}})(_e)),_e}var Ee={},it;function No(){if(it)return Ee;it=1;const e=W().getSymbolSize,s=7;return Ee.getPositions=function(t){const n=e(t);return[[0,0],[n-s,0],[0,n-s]]},Ee}var ke={},at;function Po(){return at||(at=1,(function(e){e.Patterns={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};const s={N1:3,N2:3,N3:40,N4:10};e.isValid=function(n){return n!=null&&n!==""&&!isNaN(n)&&n>=0&&n<=7},e.from=function(n){return e.isValid(n)?parseInt(n,10):void 0},e.getPenaltyN1=function(n){const o=n.size;let i=0,a=0,u=0,l=null,f=null;for(let w=0;w<o;w++){a=u=0,l=f=null;for(let b=0;b<o;b++){let h=n.get(w,b);h===l?a++:(a>=5&&(i+=s.N1+(a-5)),l=h,a=1),h=n.get(b,w),h===f?u++:(u>=5&&(i+=s.N1+(u-5)),f=h,u=1)}a>=5&&(i+=s.N1+(a-5)),u>=5&&(i+=s.N1+(u-5))}return i},e.getPenaltyN2=function(n){const o=n.size;let i=0;for(let a=0;a<o-1;a++)for(let u=0;u<o-1;u++){const l=n.get(a,u)+n.get(a,u+1)+n.get(a+1,u)+n.get(a+1,u+1);(l===4||l===0)&&i++}return i*s.N2},e.getPenaltyN3=function(n){const o=n.size;let i=0,a=0,u=0;for(let l=0;l<o;l++){a=u=0;for(let f=0;f<o;f++)a=a<<1&2047|n.get(l,f),f>=10&&(a===1488||a===93)&&i++,u=u<<1&2047|n.get(f,l),f>=10&&(u===1488||u===93)&&i++}return i*s.N3},e.getPenaltyN4=function(n){let o=0;const i=n.data.length;for(let u=0;u<i;u++)o+=n.data[u];return Math.abs(Math.ceil(o*100/i/5)-10)*s.N4};function r(t,n,o){switch(t){case e.Patterns.PATTERN000:return(n+o)%2===0;case e.Patterns.PATTERN001:return n%2===0;case e.Patterns.PATTERN010:return o%3===0;case e.Patterns.PATTERN011:return(n+o)%3===0;case e.Patterns.PATTERN100:return(Math.floor(n/2)+Math.floor(o/3))%2===0;case e.Patterns.PATTERN101:return n*o%2+n*o%3===0;case e.Patterns.PATTERN110:return(n*o%2+n*o%3)%2===0;case e.Patterns.PATTERN111:return(n*o%3+(n+o)%2)%2===0;default:throw new Error("bad maskPattern:"+t)}}e.applyMask=function(n,o){const i=o.size;for(let a=0;a<i;a++)for(let u=0;u<i;u++)o.isReserved(u,a)||o.xor(u,a,r(n,u,a))},e.getBestMask=function(n,o){const i=Object.keys(e.Patterns).length;let a=0,u=1/0;for(let l=0;l<i;l++){o(l),e.applyMask(l,n);const f=e.getPenaltyN1(n)+e.getPenaltyN2(n)+e.getPenaltyN3(n)+e.getPenaltyN4(n);e.applyMask(l,n),f<u&&(u=f,a=l)}return a}})(ke)),ke}var ue={},ut;function Ot(){if(ut)return ue;ut=1;const e=Je(),s=[1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,4,1,2,4,4,2,4,4,4,2,4,6,5,2,4,6,6,2,5,8,8,4,5,8,8,4,5,8,11,4,8,10,11,4,9,12,16,4,9,16,16,6,10,12,18,6,10,17,16,6,11,16,19,6,13,18,21,7,14,21,25,8,16,20,25,8,17,23,25,9,17,23,34,9,18,25,30,10,20,27,32,12,21,29,35,12,23,34,37,12,25,34,40,13,26,35,42,14,28,38,45,15,29,40,48,16,31,43,51,17,33,45,54,18,35,48,57,19,37,51,60,19,38,53,63,20,40,56,66,21,43,59,70,22,45,62,74,24,47,65,77,25,49,68,81],r=[7,10,13,17,10,16,22,28,15,26,36,44,20,36,52,64,26,48,72,88,36,64,96,112,40,72,108,130,48,88,132,156,60,110,160,192,72,130,192,224,80,150,224,264,96,176,260,308,104,198,288,352,120,216,320,384,132,240,360,432,144,280,408,480,168,308,448,532,180,338,504,588,196,364,546,650,224,416,600,700,224,442,644,750,252,476,690,816,270,504,750,900,300,560,810,960,312,588,870,1050,336,644,952,1110,360,700,1020,1200,390,728,1050,1260,420,784,1140,1350,450,812,1200,1440,480,868,1290,1530,510,924,1350,1620,540,980,1440,1710,570,1036,1530,1800,570,1064,1590,1890,600,1120,1680,1980,630,1204,1770,2100,660,1260,1860,2220,720,1316,1950,2310,750,1372,2040,2430];return ue.getBlocksCount=function(n,o){switch(o){case e.L:return s[(n-1)*4+0];case e.M:return s[(n-1)*4+1];case e.Q:return s[(n-1)*4+2];case e.H:return s[(n-1)*4+3];default:return}},ue.getTotalCodewordsCount=function(n,o){switch(o){case e.L:return r[(n-1)*4+0];case e.M:return r[(n-1)*4+1];case e.Q:return r[(n-1)*4+2];case e.H:return r[(n-1)*4+3];default:return}},ue}var Be={},ne={},lt;function Do(){if(lt)return ne;lt=1;const e=new Uint8Array(512),s=new Uint8Array(256);return(function(){let t=1;for(let n=0;n<255;n++)e[n]=t,s[t]=n,t<<=1,t&256&&(t^=285);for(let n=255;n<512;n++)e[n]=e[n-255]})(),ne.log=function(t){if(t<1)throw new Error("log("+t+")");return s[t]},ne.exp=function(t){return e[t]},ne.mul=function(t,n){return t===0||n===0?0:e[s[t]+s[n]]},ne}var ct;function Lo(){return ct||(ct=1,(function(e){const s=Do();e.mul=function(t,n){const o=new Uint8Array(t.length+n.length-1);for(let i=0;i<t.length;i++)for(let a=0;a<n.length;a++)o[i+a]^=s.mul(t[i],n[a]);return o},e.mod=function(t,n){let o=new Uint8Array(t);for(;o.length-n.length>=0;){const i=o[0];for(let u=0;u<n.length;u++)o[u]^=s.mul(n[u],i);let a=0;for(;a<o.length&&o[a]===0;)a++;o=o.slice(a)}return o},e.generateECPolynomial=function(t){let n=new Uint8Array([1]);for(let o=0;o<t;o++)n=e.mul(n,new Uint8Array([1,s.exp(o)]));return n}})(Be)),Be}var Ie,dt;function qo(){if(dt)return Ie;dt=1;const e=Lo();function s(r){this.genPoly=void 0,this.degree=r,this.degree&&this.initialize(this.degree)}return s.prototype.initialize=function(t){this.degree=t,this.genPoly=e.generateECPolynomial(this.degree)},s.prototype.encode=function(t){if(!this.genPoly)throw new Error("Encoder not initialized");const n=new Uint8Array(t.length+this.degree);n.set(t);const o=e.mod(n,this.genPoly),i=this.degree-o.length;if(i>0){const a=new Uint8Array(this.degree);return a.set(o,i),a}return o},Ie=s,Ie}var Ae={},Re={},Te={},ft;function jt(){return ft||(ft=1,Te.isValid=function(s){return!isNaN(s)&&s>=1&&s<=40}),Te}var H={},ht;function zt(){if(ht)return H;ht=1;const e="[0-9]+",s="[A-Z $%*+\\-./:]+";let r="(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+";r=r.replace(/u/g,"\\u");const t="(?:(?![A-Z0-9 $%*+\\-./:]|"+r+`)(?:.|[\r
2
- ]))+`;H.KANJI=new RegExp(r,"g"),H.BYTE_KANJI=new RegExp("[^A-Z0-9 $%*+\\-./:]+","g"),H.BYTE=new RegExp(t,"g"),H.NUMERIC=new RegExp(e,"g"),H.ALPHANUMERIC=new RegExp(s,"g");const n=new RegExp("^"+r+"$"),o=new RegExp("^"+e+"$"),i=new RegExp("^[A-Z0-9 $%*+\\-./:]+$");return H.testKanji=function(u){return n.test(u)},H.testNumeric=function(u){return o.test(u)},H.testAlphanumeric=function(u){return i.test(u)},H}var gt;function Z(){return gt||(gt=1,(function(e){const s=jt(),r=zt();e.NUMERIC={id:"Numeric",bit:1,ccBits:[10,12,14]},e.ALPHANUMERIC={id:"Alphanumeric",bit:2,ccBits:[9,11,13]},e.BYTE={id:"Byte",bit:4,ccBits:[8,16,16]},e.KANJI={id:"Kanji",bit:8,ccBits:[8,10,12]},e.MIXED={bit:-1},e.getCharCountIndicator=function(o,i){if(!o.ccBits)throw new Error("Invalid mode: "+o);if(!s.isValid(i))throw new Error("Invalid version: "+i);return i>=1&&i<10?o.ccBits[0]:i<27?o.ccBits[1]:o.ccBits[2]},e.getBestModeForData=function(o){return r.testNumeric(o)?e.NUMERIC:r.testAlphanumeric(o)?e.ALPHANUMERIC:r.testKanji(o)?e.KANJI:e.BYTE},e.toString=function(o){if(o&&o.id)return o.id;throw new Error("Invalid mode")},e.isValid=function(o){return o&&o.bit&&o.ccBits};function t(n){if(typeof n!="string")throw new Error("Param is not a string");switch(n.toLowerCase()){case"numeric":return e.NUMERIC;case"alphanumeric":return e.ALPHANUMERIC;case"kanji":return e.KANJI;case"byte":return e.BYTE;default:throw new Error("Unknown mode: "+n)}}e.from=function(o,i){if(e.isValid(o))return o;try{return t(o)}catch{return i}}})(Re)),Re}var mt;function Fo(){return mt||(mt=1,(function(e){const s=W(),r=Ot(),t=Je(),n=Z(),o=jt(),i=7973,a=s.getBCHDigit(i);function u(b,h,d){for(let g=1;g<=40;g++)if(h<=e.getCapacity(g,d,b))return g}function l(b,h){return n.getCharCountIndicator(b,h)+4}function f(b,h){let d=0;return b.forEach(function(g){const N=l(g.mode,h);d+=N+g.getBitsLength()}),d}function w(b,h){for(let d=1;d<=40;d++)if(f(b,d)<=e.getCapacity(d,h,n.MIXED))return d}e.from=function(h,d){return o.isValid(h)?parseInt(h,10):d},e.getCapacity=function(h,d,g){if(!o.isValid(h))throw new Error("Invalid QR Code version");typeof g>"u"&&(g=n.BYTE);const N=s.getSymbolTotalCodewords(h),A=r.getTotalCodewordsCount(h,d),P=(N-A)*8;if(g===n.MIXED)return P;const c=P-l(g,h);switch(g){case n.NUMERIC:return Math.floor(c/10*3);case n.ALPHANUMERIC:return Math.floor(c/11*2);case n.KANJI:return Math.floor(c/13);case n.BYTE:default:return Math.floor(c/8)}},e.getBestVersionForData=function(h,d){let g;const N=t.from(d,t.M);if(Array.isArray(h)){if(h.length>1)return w(h,N);if(h.length===0)return 1;g=h[0]}else g=h;return u(g.mode,g.getLength(),N)},e.getEncodedBits=function(h){if(!o.isValid(h)||h<7)throw new Error("Invalid QR Code version");let d=h<<12;for(;s.getBCHDigit(d)-a>=0;)d^=i<<s.getBCHDigit(d)-a;return h<<12|d}})(Ae)),Ae}var Me={},yt;function Uo(){if(yt)return Me;yt=1;const e=W(),s=1335,r=21522,t=e.getBCHDigit(s);return Me.getEncodedBits=function(o,i){const a=o.bit<<3|i;let u=a<<10;for(;e.getBCHDigit(u)-t>=0;)u^=s<<e.getBCHDigit(u)-t;return(a<<10|u)^r},Me}var Ne={},Pe,pt;function Ko(){if(pt)return Pe;pt=1;const e=Z();function s(r){this.mode=e.NUMERIC,this.data=r.toString()}return s.getBitsLength=function(t){return 10*Math.floor(t/3)+(t%3?t%3*3+1:0)},s.prototype.getLength=function(){return this.data.length},s.prototype.getBitsLength=function(){return s.getBitsLength(this.data.length)},s.prototype.write=function(t){let n,o,i;for(n=0;n+3<=this.data.length;n+=3)o=this.data.substr(n,3),i=parseInt(o,10),t.put(i,10);const a=this.data.length-n;a>0&&(o=this.data.substr(n),i=parseInt(o,10),t.put(i,a*3+1))},Pe=s,Pe}var De,wt;function Vo(){if(wt)return De;wt=1;const e=Z(),s=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"," ","$","%","*","+","-",".","/",":"];function r(t){this.mode=e.ALPHANUMERIC,this.data=t}return r.getBitsLength=function(n){return 11*Math.floor(n/2)+6*(n%2)},r.prototype.getLength=function(){return this.data.length},r.prototype.getBitsLength=function(){return r.getBitsLength(this.data.length)},r.prototype.write=function(n){let o;for(o=0;o+2<=this.data.length;o+=2){let i=s.indexOf(this.data[o])*45;i+=s.indexOf(this.data[o+1]),n.put(i,11)}this.data.length%2&&n.put(s.indexOf(this.data[o]),6)},De=r,De}var Le,bt;function Ho(){if(bt)return Le;bt=1;const e=Z();function s(r){this.mode=e.BYTE,typeof r=="string"?this.data=new TextEncoder().encode(r):this.data=new Uint8Array(r)}return s.getBitsLength=function(t){return t*8},s.prototype.getLength=function(){return this.data.length},s.prototype.getBitsLength=function(){return s.getBitsLength(this.data.length)},s.prototype.write=function(r){for(let t=0,n=this.data.length;t<n;t++)r.put(this.data[t],8)},Le=s,Le}var qe,vt;function Oo(){if(vt)return qe;vt=1;const e=Z(),s=W();function r(t){this.mode=e.KANJI,this.data=t}return r.getBitsLength=function(n){return n*13},r.prototype.getLength=function(){return this.data.length},r.prototype.getBitsLength=function(){return r.getBitsLength(this.data.length)},r.prototype.write=function(t){let n;for(n=0;n<this.data.length;n++){let o=s.toSJIS(this.data[n]);if(o>=33088&&o<=40956)o-=33088;else if(o>=57408&&o<=60351)o-=49472;else throw new Error("Invalid SJIS character: "+this.data[n]+`
3
- Make sure your charset is UTF-8`);o=(o>>>8&255)*192+(o&255),t.put(o,13)}},qe=r,qe}var Fe={exports:{}},Ct;function jo(){return Ct||(Ct=1,(function(e){var s={single_source_shortest_paths:function(r,t,n){var o={},i={};i[t]=0;var a=s.PriorityQueue.make();a.push(t,0);for(var u,l,f,w,b,h,d,g,N;!a.empty();){u=a.pop(),l=u.value,w=u.cost,b=r[l]||{};for(f in b)b.hasOwnProperty(f)&&(h=b[f],d=w+h,g=i[f],N=typeof i[f]>"u",(N||g>d)&&(i[f]=d,a.push(f,d),o[f]=l))}if(typeof n<"u"&&typeof i[n]>"u"){var A=["Could not find a path from ",t," to ",n,"."].join("");throw new Error(A)}return o},extract_shortest_path_from_predecessor_list:function(r,t){for(var n=[],o=t;o;)n.push(o),r[o],o=r[o];return n.reverse(),n},find_path:function(r,t,n){var o=s.single_source_shortest_paths(r,t,n);return s.extract_shortest_path_from_predecessor_list(o,n)},PriorityQueue:{make:function(r){var t=s.PriorityQueue,n={},o;r=r||{};for(o in t)t.hasOwnProperty(o)&&(n[o]=t[o]);return n.queue=[],n.sorter=r.sorter||t.default_sorter,n},default_sorter:function(r,t){return r.cost-t.cost},push:function(r,t){var n={value:r,cost:t};this.queue.push(n),this.queue.sort(this.sorter)},pop:function(){return this.queue.shift()},empty:function(){return this.queue.length===0}}};e.exports=s})(Fe)),Fe.exports}var St;function zo(){return St||(St=1,(function(e){const s=Z(),r=Ko(),t=Vo(),n=Ho(),o=Oo(),i=zt(),a=W(),u=jo();function l(A){return unescape(encodeURIComponent(A)).length}function f(A,P,c){const S=[];let I;for(;(I=A.exec(c))!==null;)S.push({data:I[0],index:I.index,mode:P,length:I[0].length});return S}function w(A){const P=f(i.NUMERIC,s.NUMERIC,A),c=f(i.ALPHANUMERIC,s.ALPHANUMERIC,A);let S,I;return a.isKanjiModeEnabled()?(S=f(i.BYTE,s.BYTE,A),I=f(i.KANJI,s.KANJI,A)):(S=f(i.BYTE_KANJI,s.BYTE,A),I=[]),P.concat(c,S,I).sort(function(p,y){return p.index-y.index}).map(function(p){return{data:p.data,mode:p.mode,length:p.length}})}function b(A,P){switch(P){case s.NUMERIC:return r.getBitsLength(A);case s.ALPHANUMERIC:return t.getBitsLength(A);case s.KANJI:return o.getBitsLength(A);case s.BYTE:return n.getBitsLength(A)}}function h(A){return A.reduce(function(P,c){const S=P.length-1>=0?P[P.length-1]:null;return S&&S.mode===c.mode?(P[P.length-1].data+=c.data,P):(P.push(c),P)},[])}function d(A){const P=[];for(let c=0;c<A.length;c++){const S=A[c];switch(S.mode){case s.NUMERIC:P.push([S,{data:S.data,mode:s.ALPHANUMERIC,length:S.length},{data:S.data,mode:s.BYTE,length:S.length}]);break;case s.ALPHANUMERIC:P.push([S,{data:S.data,mode:s.BYTE,length:S.length}]);break;case s.KANJI:P.push([S,{data:S.data,mode:s.BYTE,length:l(S.data)}]);break;case s.BYTE:P.push([{data:S.data,mode:s.BYTE,length:l(S.data)}])}}return P}function g(A,P){const c={},S={start:{}};let I=["start"];for(let C=0;C<A.length;C++){const p=A[C],y=[];for(let m=0;m<p.length;m++){const _=p[m],E=""+C+m;y.push(E),c[E]={node:_,lastCount:0},S[E]={};for(let k=0;k<I.length;k++){const B=I[k];c[B]&&c[B].node.mode===_.mode?(S[B][E]=b(c[B].lastCount+_.length,_.mode)-b(c[B].lastCount,_.mode),c[B].lastCount+=_.length):(c[B]&&(c[B].lastCount=_.length),S[B][E]=b(_.length,_.mode)+4+s.getCharCountIndicator(_.mode,P))}}I=y}for(let C=0;C<I.length;C++)S[I[C]].end=0;return{map:S,table:c}}function N(A,P){let c;const S=s.getBestModeForData(A);if(c=s.from(P,S),c!==s.BYTE&&c.bit<S.bit)throw new Error('"'+A+'" cannot be encoded with mode '+s.toString(c)+`.
4
- Suggested mode is: `+s.toString(S));switch(c===s.KANJI&&!a.isKanjiModeEnabled()&&(c=s.BYTE),c){case s.NUMERIC:return new r(A);case s.ALPHANUMERIC:return new t(A);case s.KANJI:return new o(A);case s.BYTE:return new n(A)}}e.fromArray=function(P){return P.reduce(function(c,S){return typeof S=="string"?c.push(N(S,null)):S.data&&c.push(N(S.data,S.mode)),c},[])},e.fromString=function(P,c){const S=w(P,a.isKanjiModeEnabled()),I=d(S),C=g(I,c),p=u.find_path(C.map,"start","end"),y=[];for(let m=1;m<p.length-1;m++)y.push(C.table[p[m]].node);return e.fromArray(h(y))},e.rawSplit=function(P){return e.fromArray(w(P,a.isKanjiModeEnabled()))}})(Ne)),Ne}var _t;function xo(){if(_t)return be;_t=1;const e=W(),s=Je(),r=Ro(),t=To(),n=Mo(),o=No(),i=Po(),a=Ot(),u=qo(),l=Fo(),f=Uo(),w=Z(),b=zo();function h(C,p){const y=C.size,m=o.getPositions(p);for(let _=0;_<m.length;_++){const E=m[_][0],k=m[_][1];for(let B=-1;B<=7;B++)if(!(E+B<=-1||y<=E+B))for(let M=-1;M<=7;M++)k+M<=-1||y<=k+M||(B>=0&&B<=6&&(M===0||M===6)||M>=0&&M<=6&&(B===0||B===6)||B>=2&&B<=4&&M>=2&&M<=4?C.set(E+B,k+M,!0,!0):C.set(E+B,k+M,!1,!0))}}function d(C){const p=C.size;for(let y=8;y<p-8;y++){const m=y%2===0;C.set(y,6,m,!0),C.set(6,y,m,!0)}}function g(C,p){const y=n.getPositions(p);for(let m=0;m<y.length;m++){const _=y[m][0],E=y[m][1];for(let k=-2;k<=2;k++)for(let B=-2;B<=2;B++)k===-2||k===2||B===-2||B===2||k===0&&B===0?C.set(_+k,E+B,!0,!0):C.set(_+k,E+B,!1,!0)}}function N(C,p){const y=C.size,m=l.getEncodedBits(p);let _,E,k;for(let B=0;B<18;B++)_=Math.floor(B/3),E=B%3+y-8-3,k=(m>>B&1)===1,C.set(_,E,k,!0),C.set(E,_,k,!0)}function A(C,p,y){const m=C.size,_=f.getEncodedBits(p,y);let E,k;for(E=0;E<15;E++)k=(_>>E&1)===1,E<6?C.set(E,8,k,!0):E<8?C.set(E+1,8,k,!0):C.set(m-15+E,8,k,!0),E<8?C.set(8,m-E-1,k,!0):E<9?C.set(8,15-E-1+1,k,!0):C.set(8,15-E-1,k,!0);C.set(m-8,8,1,!0)}function P(C,p){const y=C.size;let m=-1,_=y-1,E=7,k=0;for(let B=y-1;B>0;B-=2)for(B===6&&B--;;){for(let M=0;M<2;M++)if(!C.isReserved(_,B-M)){let V=!1;k<p.length&&(V=(p[k]>>>E&1)===1),C.set(_,B-M,V),E--,E===-1&&(k++,E=7)}if(_+=m,_<0||y<=_){_-=m,m=-m;break}}}function c(C,p,y){const m=new r;y.forEach(function(M){m.put(M.mode.bit,4),m.put(M.getLength(),w.getCharCountIndicator(M.mode,C)),M.write(m)});const _=e.getSymbolTotalCodewords(C),E=a.getTotalCodewordsCount(C,p),k=(_-E)*8;for(m.getLengthInBits()+4<=k&&m.put(0,4);m.getLengthInBits()%8!==0;)m.putBit(0);const B=(k-m.getLengthInBits())/8;for(let M=0;M<B;M++)m.put(M%2?17:236,8);return S(m,C,p)}function S(C,p,y){const m=e.getSymbolTotalCodewords(p),_=a.getTotalCodewordsCount(p,y),E=m-_,k=a.getBlocksCount(p,y),B=m%k,M=k-B,V=Math.floor(m/k),K=Math.floor(E/k),q=K+1,Ye=V-K,$t=new u(Ye);let he=0;const ie=new Array(k),Qe=new Array(k);let ge=0;const Jt=new Uint8Array(C.buffer);for(let X=0;X<k;X++){const ye=X<M?K:q;ie[X]=Jt.slice(he,he+ye),Qe[X]=$t.encode(ie[X]),he+=ye,ge=Math.max(ge,ye)}const me=new Uint8Array(m);let Ge=0,O,j;for(O=0;O<ge;O++)for(j=0;j<k;j++)O<ie[j].length&&(me[Ge++]=ie[j][O]);for(O=0;O<Ye;O++)for(j=0;j<k;j++)me[Ge++]=Qe[j][O];return me}function I(C,p,y,m){let _;if(Array.isArray(C))_=b.fromArray(C);else if(typeof C=="string"){let V=p;if(!V){const K=b.rawSplit(C);V=l.getBestVersionForData(K,y)}_=b.fromString(C,V||40)}else throw new Error("Invalid data");const E=l.getBestVersionForData(_,y);if(!E)throw new Error("The amount of data is too big to be stored in a QR Code");if(!p)p=E;else if(p<E)throw new Error(`
5
- The chosen QR Code version cannot contain this amount of data.
6
- Minimum version required to store current data is: `+E+`.
7
- `);const k=c(p,y,_),B=e.getSymbolSize(p),M=new t(B);return h(M,p),d(M),g(M,p),A(M,y,0),p>=7&&N(M,p),P(M,k),isNaN(m)&&(m=i.getBestMask(M,A.bind(null,M,y))),i.applyMask(m,M),A(M,y,m),{modules:M,version:p,errorCorrectionLevel:y,maskPattern:m,segments:_}}return be.create=function(p,y){if(typeof p>"u"||p==="")throw new Error("No input text");let m=s.M,_,E;return typeof y<"u"&&(m=s.from(y.errorCorrectionLevel,s.M),_=l.from(y.version),E=i.from(y.maskPattern),y.toSJISFunc&&e.setToSJISFunction(y.toSJISFunc)),I(p,_,m,E)},be}var Ue={},Ke={},Et;function xt(){return Et||(Et=1,(function(e){function s(r){if(typeof r=="number"&&(r=r.toString()),typeof r!="string")throw new Error("Color should be defined as hex string");let t=r.slice().replace("#","").split("");if(t.length<3||t.length===5||t.length>8)throw new Error("Invalid hex color: "+r);(t.length===3||t.length===4)&&(t=Array.prototype.concat.apply([],t.map(function(o){return[o,o]}))),t.length===6&&t.push("F","F");const n=parseInt(t.join(""),16);return{r:n>>24&255,g:n>>16&255,b:n>>8&255,a:n&255,hex:"#"+t.slice(0,6).join("")}}e.getOptions=function(t){t||(t={}),t.color||(t.color={});const n=typeof t.margin>"u"||t.margin===null||t.margin<0?4:t.margin,o=t.width&&t.width>=21?t.width:void 0,i=t.scale||4;return{width:o,scale:o?4:i,margin:n,color:{dark:s(t.color.dark||"#000000ff"),light:s(t.color.light||"#ffffffff")},type:t.type,rendererOpts:t.rendererOpts||{}}},e.getScale=function(t,n){return n.width&&n.width>=t+n.margin*2?n.width/(t+n.margin*2):n.scale},e.getImageWidth=function(t,n){const o=e.getScale(t,n);return Math.floor((t+n.margin*2)*o)},e.qrToImageData=function(t,n,o){const i=n.modules.size,a=n.modules.data,u=e.getScale(i,o),l=Math.floor((i+o.margin*2)*u),f=o.margin*u,w=[o.color.light,o.color.dark];for(let b=0;b<l;b++)for(let h=0;h<l;h++){let d=(b*l+h)*4,g=o.color.light;if(b>=f&&h>=f&&b<l-f&&h<l-f){const N=Math.floor((b-f)/u),A=Math.floor((h-f)/u);g=w[a[N*i+A]?1:0]}t[d++]=g.r,t[d++]=g.g,t[d++]=g.b,t[d]=g.a}}})(Ke)),Ke}var kt;function $o(){return kt||(kt=1,(function(e){const s=xt();function r(n,o,i){n.clearRect(0,0,o.width,o.height),o.style||(o.style={}),o.height=i,o.width=i,o.style.height=i+"px",o.style.width=i+"px"}function t(){try{return document.createElement("canvas")}catch{throw new Error("You need to specify a canvas element")}}e.render=function(o,i,a){let u=a,l=i;typeof u>"u"&&(!i||!i.getContext)&&(u=i,i=void 0),i||(l=t()),u=s.getOptions(u);const f=s.getImageWidth(o.modules.size,u),w=l.getContext("2d"),b=w.createImageData(f,f);return s.qrToImageData(b.data,o,u),r(w,l,f),w.putImageData(b,0,0),l},e.renderToDataURL=function(o,i,a){let u=a;typeof u>"u"&&(!i||!i.getContext)&&(u=i,i=void 0),u||(u={});const l=e.render(o,i,u),f=u.type||"image/png",w=u.rendererOpts||{};return l.toDataURL(f,w.quality)}})(Ue)),Ue}var Ve={},Bt;function Jo(){if(Bt)return Ve;Bt=1;const e=xt();function s(n,o){const i=n.a/255,a=o+'="'+n.hex+'"';return i<1?a+" "+o+'-opacity="'+i.toFixed(2).slice(1)+'"':a}function r(n,o,i){let a=n+o;return typeof i<"u"&&(a+=" "+i),a}function t(n,o,i){let a="",u=0,l=!1,f=0;for(let w=0;w<n.length;w++){const b=Math.floor(w%o),h=Math.floor(w/o);!b&&!l&&(l=!0),n[w]?(f++,w>0&&b>0&&n[w-1]||(a+=l?r("M",b+i,.5+h+i):r("m",u,0),u=0,l=!1),b+1<o&&n[w+1]||(a+=r("h",f),f=0)):u++}return a}return Ve.render=function(o,i,a){const u=e.getOptions(i),l=o.modules.size,f=o.modules.data,w=l+u.margin*2,b=u.color.light.a?"<path "+s(u.color.light,"fill")+' d="M0 0h'+w+"v"+w+'H0z"/>':"",h="<path "+s(u.color.dark,"stroke")+' d="'+t(f,l,u.margin)+'"/>',d='viewBox="0 0 '+w+" "+w+'"',N='<svg xmlns="http://www.w3.org/2000/svg" '+(u.width?'width="'+u.width+'" height="'+u.width+'" ':"")+d+' shape-rendering="crispEdges">'+b+h+`</svg>
8
- `;return typeof a=="function"&&a(null,N),N},Ve}var It;function Yo(){if(It)return te;It=1;const e=Ao(),s=xo(),r=$o(),t=Jo();function n(o,i,a,u,l){const f=[].slice.call(arguments,1),w=f.length,b=typeof f[w-1]=="function";if(!b&&!e())throw new Error("Callback required as last argument");if(b){if(w<2)throw new Error("Too few arguments provided");w===2?(l=a,a=i,i=u=void 0):w===3&&(i.getContext&&typeof l>"u"?(l=u,u=void 0):(l=u,u=a,a=i,i=void 0))}else{if(w<1)throw new Error("Too few arguments provided");return w===1?(a=i,i=u=void 0):w===2&&!i.getContext&&(u=a,a=i,i=void 0),new Promise(function(h,d){try{const g=s.create(a,u);h(o(g,i,u))}catch(g){d(g)}})}try{const h=s.create(a,u);l(null,o(h,i,u))}catch(h){l(h)}}return te.create=s.create,te.toCanvas=n.bind(null,r.render),te.toDataURL=n.bind(null,r.renderToDataURL),te.toString=n.bind(null,function(o,i,a){return t.render(o,a)}),te}var Qo=Yo();const Go=Io(Qo),Wo={class:"qr-display"},Zo={class:"qr-section"},Xo=["href","onKeydown"],er={key:0,class:"link-text"},tr={__name:"QRCodeDisplay",props:{url:{type:String,required:!0},showLink:{type:Boolean,default:!1}},emits:["copied"],setup(e,{emit:s}){const r=e,t=s,n=F(null),o=x(()=>r.url?r.url.replace(/^https?:\/\//,""):"");function i(){if(!(!r.url||!n.value))try{n.value.getContext("2d").clearRect(0,0,n.value.width,n.value.height),Go.toCanvas(n.value,r.url,{scale:6,margin:0,color:{dark:"#000000",light:"#FFFFFF"}}),n.value.removeAttribute("style")}catch(u){console.error("QR code generation failed:",u)}}async function a(){if(r.url)try{await navigator.clipboard.writeText(r.url),t("copied")}catch(u){console.error("Failed to copy link:",u)}}return He(()=>r.url,()=>{i()},{immediate:!0}),He(n,()=>{n.value&&r.url&&i()},{immediate:!0}),(u,l)=>(T(),R("div",Wo,[v("div",Zo,[v("a",{href:e.url,onClick:de(a,["prevent"]),class:"qr-link",title:"Click to copy link",tabindex:"0",onKeydown:ln(de(a,["prevent"]),["enter"])},[v("canvas",{ref_key:"qrCanvas",ref:n,class:"qr-code"},null,512),e.showLink&&e.url?(T(),R("div",er,D(o.value),1)):L("",!0)],40,Xo)])]))}},nr=Y(tr,[["__scopeId","data-v-727427c4"]]),or={class:"device-dialog",role:"dialog","aria-modal":"true","aria-labelledby":"regTitle"},rr={class:"reg-header-row"},sr={id:"regTitle",class:"reg-title"},ir={key:0},ar={key:1},ur={class:"device-link-section"},lr={key:0,class:"expiry-note"},cr={__name:"RegistrationLinkModal",props:{endpoint:{type:String,required:!0},userName:{type:String,default:""}},emits:["close","copied"],setup(e,{emit:s}){const r=e,t=s,n=F(null),o=F(null),i=F(null),a=F(null),u=F(null);async function l(){try{const d=await Q(r.endpoint,{method:"POST"});if(d.url){if(o.value=d.url,i.value=d.expires?new Date(d.expires):null,await ze(),n.value){n.value.showModal();const g=a.value;(g?.querySelector(".btn-primary")||g?.querySelector("button"))?.focus()}}else t("close")}catch{t("close")}}function f(){t("copied")}const w=d=>{const g=z(d)},b=d=>{const g=z(d);g&&(d.preventDefault(),(g==="down"||g==="up")&&a.value?.querySelector("button")?.focus())},h=d=>{const g=z(d);g&&(d.preventDefault(),(g==="up"||g==="down")&&document.querySelector(".qr-link")?.focus())};return qt(()=>{u.value=document.activeElement,l()}),Ft(()=>{const d=u.value;d&&document.body.contains(d)&&!d.disabled&&d.focus()}),(d,g)=>(T(),R("dialog",{ref_key:"dialog",ref:n,onClose:g[2]||(g[2]=N=>d.$emit("close")),onKeydown:w},[v("div",or,[v("div",rr,[v("h2",sr,[g[3]||(g[3]=xe(" 📱 ",-1)),e.userName?(T(),R("span",ir,"Registration for "+D(e.userName),1)):(T(),R("span",ar,"Add Another Device"))]),v("button",{class:"icon-btn",onClick:g[0]||(g[0]=N=>d.$emit("close")),"aria-label":"Close",tabindex:"-1"},"✕")]),v("div",ur,[g[4]||(g[4]=v("p",{class:"reg-help"}," Scan this QR code on the new device, or copy the link and open it there. ",-1)),cn(nr,{url:o.value,"show-link":!0,onCopied:f,onKeydown:b},null,8,["url"]),i.value?(T(),R("p",lr," This link expires "+D(U(G)(i.value).toLowerCase())+". ",1)):L("",!0)]),v("div",{class:"reg-actions",ref_key:"actionsRow",ref:a,onKeydown:h},[v("button",{class:"btn-secondary",onClick:g[1]||(g[1]=N=>d.$emit("close"))},"Close")],544)])],544))}},Ir=Y(cr,[["__scopeId","data-v-e04dd463"]]),dr={class:"loading-container"},fr={__name:"LoadingView",props:{message:{type:String,default:"Loading..."}},setup(e){return(s,r)=>(T(),R("div",dr,[r[0]||(r[0]=v("div",{class:"loading-spinner"},null,-1)),v("p",null,D(e.message),1)]))}},Ar=Y(fr,[["__scopeId","data-v-130f5abf"]]),hr={class:"message-container"},gr={class:"message-content"},mr={class:"button-row"},yr={__name:"AccessDenied",emits:["reload"],setup(e){return(s,r)=>(T(),R("div",hr,[v("div",gr,[r[2]||(r[2]=v("h2",null,"🔒 Access Denied",-1)),v("div",mr,[v("button",{class:"btn-secondary",onClick:r[0]||(r[0]=(...t)=>U(We)&&U(We)(...t))},"Back"),v("button",{class:"btn-primary",onClick:r[1]||(r[1]=t=>s.$emit("reload"))},"Reload Page")])])]))}},Rr=Y(yr,[["__scopeId","data-v-744305d5"]]);export{Rr as A,Cr as B,Ar as L,Er as M,kr as N,Ir as R,_r as U,Sr as _,Br as a,vr as b,br as c,$e as u};
@@ -1 +0,0 @@
1
- import{_ as G,r as m,c as S,w as Y,o as J,a as K,b as i,d as l,e as t,t as p,F as N,i as j,f as P,m as Q,p as Z,O as ee,g as te,a1 as se,x as ae,a7 as O,a6 as H,G as ne,n as oe,a8 as ie,a4 as le}from"./_plugin-vue_export-helper-rKFEraYH.js";import{c as re,s as ce,b as ue,w as z}from"./pow-2N9bxgAo.js";const de={class:"remote-auth-inline"},he={key:0,class:"success-section"},ve={class:"success-message"},fe={key:1,class:"error-section"},me={class:"error-message"},ge={key:2,class:"auth-display"},_e={class:"auth-content"},pe={class:"pairing-code-section"},we={class:"slot-machine","aria-hidden":"true"},ye={class:"slot-word"},ke={class:"site-url"},be={key:3,class:"auth-display"},$e={class:"auth-content"},Ae={key:0,class:"pairing-code-section"},Re={class:"slot-machine stopped"},Se={class:"slot-word"},Ce={class:"site-url"},Pe={class:"waiting-indicator"},Te={__name:"RemoteAuthRequest",props:{active:{type:Boolean,default:!1}},emits:["authenticated","cancelled","error","register"],setup(w,{expose:M,emit:F}){const $=w,g=F,v=m(null),y=m(!1),n=m(null),A=m("connecting"),_=m(null),u=m(["","",""]);let a=null,k=null;const I=S(()=>v.value?v.value.replace(/\./g," "):""),b=S(()=>{if(!_.value)return"";const s=(_.value.auth_site_url||`${location.protocol}//${location.host}/auth/`).replace(/^https?:\/\//,"");return s.endsWith("/")?s.slice(0,-1):s}),E=S(()=>A.value==="authenticating"?"Complete on another device…":"Waiting for authentication…"),x=S(()=>"Authenticated successfully!");function C(){return z[Math.floor(Math.random()*z.length)]}function B(){u.value=[C(),C(),C()];const c=20,s=[setInterval(()=>{const o=[...u.value];o[0]=C(),u.value=o},140),setInterval(()=>{const o=[...u.value];o[1]=C(),u.value=o},170),setInterval(()=>{const o=[...u.value];o[2]=C(),u.value=o},200)];k=s,setTimeout(()=>{s.forEach(o=>clearInterval(o)),k=null},c*170)}function f(){k&&(Array.isArray(k)?k.forEach(c=>clearInterval(c)):clearInterval(k),k=null)}async function U(){n.value=null,y.value=!1,v.value=null,A.value="connecting",B();try{_.value=await Q();const c=_.value?.auth_host,s="/auth/ws/remote-auth/request",o=c&&location.host!==c?`//${c}${s}`:s;a=await Z(o);const R=await a.receive_json();if(R.pow){const h=re(R.pow.challenge),V=await ce(h,R.pow.work);a.send_json({pow:ue(V),action:"login"})}const T=await a.receive_json();if(T.status)throw new Error(T.detail||`Failed to create remote auth request: ${T.status}`);for(v.value=T.pairing_code,f(),A.value="waiting";;){const h=await a.receive_json();if(h.status==="locked")A.value="authenticating";else if(h.status==="paired")A.value="authenticating";else if(h.status==="authenticated"){y.value=!0,g("authenticated",{session_token:h.session_token});break}else{if(h.status==="denied")throw new Error("Access denied");if(h.status==="completed"){h.reset_token&&(y.value=!0,g("register",h.reset_token));break}else if(h.status==="error"||h.detail)throw new Error(h.detail||"Remote authentication failed")}}}catch(c){console.error("Remote authentication error:",c);const s=c.message||"Authentication failed";n.value=s,g("error",s)}finally{a&&(a.close(),a=null)}}function W(){U()}function L(){a&&(a.close(),a=null),g("cancelled")}return Y(()=>$.active,c=>{c&&!v.value&&!n.value&&!y.value&&U()}),J(()=>{$.active&&U()}),K(()=>{a&&(a.close(),a=null),f()}),M({retry:W,cancel:L}),(c,s)=>(l(),i("div",de,[y.value?(l(),i("div",he,[t("p",ve,"✅ "+p(x.value),1)])):n.value?(l(),i("div",fe,[t("p",me,p(n.value),1),t("button",{class:"btn-primary",onClick:W,style:{"margin-top":"0.75rem"}},"Try Again")])):A.value==="connecting"?(l(),i("div",ge,[t("div",_e,[t("div",pe,[s[0]||(s[0]=t("p",{class:"pairing-label"},"Enter the code words:",-1)),t("div",we,[(l(!0),i(N,null,j(u.value,(o,R)=>(l(),i("div",{class:"slot-reel",key:R},[t("div",ye,p(o),1)]))),128))]),t("p",ke,p(b.value),1)])]),s[1]||(s[1]=t("div",{class:"waiting-indicator"},[t("div",{class:"spinner-small"}),t("span",null,"Generating code…")],-1))])):(l(),i("div",be,[t("div",$e,[v.value?(l(),i("div",Ae,[s[2]||(s[2]=t("p",{class:"pairing-label"},"Enter the code words:",-1)),t("div",Re,[(l(!0),i(N,null,j(I.value.split(" "),(o,R)=>(l(),i("div",{class:"slot-reel",key:R},[t("div",Se,p(o),1)]))),128))]),t("p",Ce,p(b.value),1)])):P("",!0)]),t("div",Pe,[s[3]||(s[3]=t("div",{class:"spinner-small"},null,-1)),t("span",null,p(E.value),1)])]))]))}},Ee=G(Te,[["__scopeId","data-v-1280e25b"]]),Ie={class:"app-shell"},Ue={key:0,class:"global-status",style:{display:"block"}},We={class:"view-root"},Le={key:0,class:"surface surface--tight"},Me={class:"view-header center"},Fe={key:0,class:"user-line"},xe=["innerHTML"],Be={class:"section-block"},Ve={class:"section-body center"},Oe={key:0,class:"auth-view"},qe=["disabled"],De=["disabled"],Ne=["disabled"],je=["disabled"],He={key:1,class:"auth-view"},ze={__name:"RestrictedAuth",props:{mode:{type:String,default:"login",validator:w=>["login","reauth","forbidden"].includes(w)}},emits:["authenticated","forbidden","logout","back","home","auth-error"],setup(w,{expose:M,emit:F}){const $=w,g=F,v=ee({show:!1,message:"",type:"info"}),y=m(!0),n=m(!1),A=m(null),_=m(null),u=m("initial"),a=m("local"),k=m(null);let I=null;const b=S(()=>!!_.value?.authenticated),E=S(()=>y.value?!1:$.mode==="reauth"?!0:u.value!=="forbidden"),x=S(()=>$.mode==="reauth"?"🔐 Additional Authentication":u.value==="forbidden"?"🚫 Forbidden":`🔐 ${A.value?.rp_name||location.origin}`),C=S(()=>$.mode==="reauth"?"Please verify your identity to continue with this action.":u.value==="forbidden"?"You lack the required permissions.":a.value==="remote"?'Confirm from your other device. Or <a href="#" class="inline-link" data-action="local">this device</a>.':E.value&&$.mode!=="reauth"?'Please sign in with your passkey. Or use <a href="#" class="inline-link" data-action="remote">another device</a>.':"Please sign in with your passkey."),B=S(()=>_.value?.user?.user_name||"User");function f(e,r="info",d=3e3){v.show=!0,v.message=e,v.type=r,I&&clearTimeout(I),d>0&&(I=setTimeout(()=>{v.show=!1},d))}async function U(){try{const e=await Q();if(A.value=e,e?.rp_name){const r=$.mode==="reauth"?"Verify Identity":b.value?"Forbidden":"Sign In";document.title=`${e.rp_name} · ${r}`}}catch(e){console.warn("Unable to load settings",e)}}async function W(){try{_.value=await O("/auth/api/user-info",{method:"POST"}),b.value&&$.mode!=="reauth"?(u.value="forbidden",g("forbidden",_.value)):u.value="login"}catch(e){console.error("Failed to load user info",e),e.status!==401&&e.status!==403&&f(H(e),"error",4e3),_.value=null,u.value="login"}}async function L(){if(!E.value||n.value)return;n.value=!0,f("Starting authentication…","info");let e;try{e=await ne.authenticate()}catch(r){n.value=!1;const d=r?.message||"Passkey authentication cancelled",D=d==="Passkey authentication cancelled";f(d,D?"info":"error",4e3),g("auth-error",{message:d,cancelled:D});return}try{await o(e)}catch(r){n.value=!1;const d=r?.message||"Failed to establish session";f(d,"error",4e3),g("auth-error",{message:d,cancelled:!1});return}n.value=!1,g("authenticated",e)}async function c(){if(!n.value){n.value=!0;try{await O("/auth/api/logout",{method:"POST"}),_.value=null,u.value="login",f("Logged out. You can sign in with a different account.","info",3e3)}catch(e){f(H(e),"error",4e3)}finally{n.value=!1}g("logout")}}function s(){const e=window.open("/auth/","passkey_auth_profile");e&&e.focus()}async function o(e){if(!e?.session_token)throw console.error("setSessionCookie called with missing session_token:",e),new Error("Authentication response missing session_token");return await O("/auth/api/set-session",{method:"POST",headers:{Authorization:`Bearer ${e.session_token}`}})}function R(){a.value="remote"}function T(){a.value="local"}async function h(e){f("Authenticated from another device!","success",2e3);try{await o(e)}catch(r){const d=r?.message||"Failed to establish session";f(d,"error",4e3),g("auth-error",{message:d,cancelled:!1});return}g("authenticated",e)}function V(e){f("Registration approved! Redirecting...","success",2e3);const r=le()||"/auth/";window.location.href=`${r}${e}`}function X(e){}function q(e){const r=e.target;if(r.tagName==="A"&&r.classList.contains("inline-link")){e.preventDefault();const d=r.dataset.action;d==="remote"?R():d==="local"&&T()}}return Y(y,e=>{e||oe(()=>ie(k.value))}),J(async()=>{await U(),await W(),y.value=!1,document.addEventListener("click",q)}),K(()=>{document.removeEventListener("click",q)}),M({showMessage:f,isAuthenticated:b,userInfo:_}),(e,r)=>(l(),i("div",Ie,[v.show?(l(),i("div",Ue,[t("div",{class:te(["status",v.type])},p(v.message),3)])):P("",!0),t("main",We,[y.value?P("",!0):(l(),i("div",Le,[t("header",Me,[t("h1",null,p(x.value),1),b.value?(l(),i("p",Fe,"👤 "+p(B.value),1)):P("",!0),t("p",{class:"view-lede",innerHTML:C.value},null,8,xe)]),t("section",Be,[t("div",Ve,[a.value==="local"?(l(),i("div",Oe,[t("div",{class:"button-row center",ref_key:"buttonRow",ref:k},[se(e.$slots,"actions",{loading:n.value,canAuthenticate:E.value,isAuthenticated:b.value,authenticate:L,logout:c,mode:w.mode},()=>[t("button",{class:"btn-secondary",disabled:n.value,onClick:r[0]||(r[0]=d=>e.$emit("back"))},"Back",8,qe),E.value?(l(),i("button",{key:0,class:"btn-primary",disabled:n.value,onClick:L},p(n.value?w.mode==="reauth"?"Verifying…":"Signing in…":w.mode==="reauth"?"Verify":"Login"),9,De)):P("",!0),b.value&&w.mode!=="reauth"?(l(),i("button",{key:1,class:"btn-danger",disabled:n.value,onClick:c},"Logout",8,Ne)):P("",!0),b.value&&w.mode!=="reauth"?(l(),i("button",{key:2,class:"btn-primary",disabled:n.value,onClick:s},"Profile",8,je)):P("",!0)])],512)])):a.value==="remote"?(l(),i("div",He,[ae(Ee,{active:a.value==="remote",onAuthenticated:h,onRegister:V,onCancelled:T,onError:X},null,8,["active"])])):P("",!0)])])]))])]))}},Je=G(ze,[["__scopeId","data-v-0a5d98ce"]]);export{Je as R};
@@ -1 +0,0 @@
1
- import{_ as de,r as k,c as I,b as v,d as m,e as n,f as x,t as C,F as A,i as Q,j as ke,C as te,B as H,D as ue,l as Se,L as we,y as W,x as re,E as $e,H as E,A as Ye,k as z,h as oe,v as ae,z as le,o as We,a as Ze,q as _e,u as Qe,w as Xe,J as et,K as tt}from"./_plugin-vue_export-helper-rKFEraYH.js";import{u as Oe,U as st,_ as nt,a as ot,R as at,N as fe,M as it,b as rt,L as lt,A as ut,B as dt,c as ct}from"./AccessDenied-aTdCvz9k.js";import{g as De}from"./helpers-DzjFIx78.js";const mt={key:0},ft=["onClick"],gt=["onClick"],yt={class:"role-names"},vt={class:"center"},pt={key:0,class:"center"},ht=["onClick"],bt={key:0,class:"permissions-section"},wt={class:"matrix-scroll"},$t=["title"],Dt=["title"],kt={class:"display-text"},St=["checked","onChange"],Ot={class:"perm-name-cell"},Rt={class:"perm-title"},Ct={class:"display-text"},At=["onClick"],Ut={class:"perm-id-info"},Pt={class:"id-text"},Et={class:"perm-domain"},Mt={class:"perm-members center"},qt={class:"perm-actions center"},Nt=["onClick"],Tt={__name:"AdminOverview",props:{info:Object,orgs:Array,permissions:Array,permissionSummary:Object,navigationDisabled:{type:Boolean,default:!1}},emits:["createOrg","openOrg","updateOrg","deleteOrg","toggleOrgPermission","openDialog","deletePermission","renamePermissionDisplay","navigateOut"],setup(o,{expose:J,emit:G}){const S=o,F=G,U=k(null),c=k(null),p=k(null),q=k(null),N=k(null),B=k(null),T=I(()=>[...S.orgs].sort((r,t)=>{const s=r.display_name.localeCompare(t.display_name);return s!==0?s:r.uuid.localeCompare(t.uuid)})),w=I(()=>[...S.permissions].sort((r,t)=>r.scope.localeCompare(t.scope))),L=I(()=>S.info?.permissions?.includes("auth:admin")??!1),$=I(()=>S.info?.permissions?.includes("auth:org:admin")??!1);function X(r){return r.roles.slice().sort((t,s)=>t.display_name.localeCompare(s.display_name)).map(t=>t.display_name).join(", ")}function Z(r,t){if(S.navigationDisabled)return;const s=H(r);if(!s)return;const D=r.target,l=D.closest("tr");if(!l)return;const d=l.closest("tbody");if(!d)return;const h=Array.from(d.querySelectorAll("tr")),R=h.indexOf(l);if(R===-1)return;if(s==="left"||s==="right"){r.preventDefault();const M=Array.from(l.querySelectorAll("a, button:not([disabled])")),K=M.indexOf(D);if(K===-1)return;s==="left"&&K>0?M[K-1].focus():s==="right"&&K<M.length-1&&M[K+1].focus();return}let V=R;if(s==="up"&&R>0)V=R-1;else if(s==="down"&&R<h.length-1)V=R+1;else if(s==="up"&&R===0){r.preventDefault(),t==="org"?te(c.value,{itemSelector:"button"}):t==="perm"&&te(N.value,{itemSelector:"button"});return}else if(s==="down"&&R===h.length-1){if(r.preventDefault(),t==="org"&&L.value&&q.value){const M=q.value.querySelector('input[type="checkbox"]');M?M.focus():te(N.value,{itemSelector:"button"})}return}if(V!==R){r.preventDefault();const K=h[V].querySelector("a, button:not([disabled])");K&&K.focus()}}function ee(r){if(S.navigationDisabled)return;const t=H(r);if(t){if(r.preventDefault(),t==="left"||t==="right")ue(c.value,r.target,t,{itemSelector:"button"});else if(t==="up")F("navigateOut","up");else if(t==="down"){const s=p.value?.querySelector("tbody tr a, tbody tr button:not([disabled])");s&&s.focus()}}}function g(r){if(S.navigationDisabled)return;const t=H(r);if(!t)return;const s=r.target;if(s.tagName!=="INPUT")return;r.preventDefault();const D=Array.from(q.value.querySelectorAll('input[type="checkbox"]')),l=D.indexOf(s);if(l===-1)return;const d=T.value.length,h=w.value.length;if(d===0||h===0)return;const R=Math.floor(l/d),V=l%d;let M=l;if(t==="left")V>0&&(M=l-1);else if(t==="right")V<d-1&&(M=l+1);else if(t==="up")if(R>0)M=l-d;else{const ie=p.value?.querySelector("tbody tr:last-child")?.querySelector("a, button:not([disabled])");ie&&ie.focus();return}else if(t==="down")if(R<h-1)M=l+d;else{te(N.value,{itemSelector:"button"});return}M!==l&&D[M]&&D[M].focus()}function u(r){if(S.navigationDisabled)return;const t=H(r);if(t){if(r.preventDefault(),t==="left"||t==="right")ue(N.value,r.target,t,{itemSelector:"button"});else if(t==="up"){const s=q.value?.querySelectorAll('input[type="checkbox"]');if(s?.length){const D=T.value.length,d=(w.value.length-1)*D;s[d]?s[d].focus():s[0].focus()}else{const l=p.value?.querySelector("tbody tr:last-child")?.querySelector("a, button:not([disabled])");l&&l.focus()}}else if(t==="down"){const s=B.value?.querySelector("tbody tr button:not([disabled])");s&&s.focus()}}}function f(){if(L.value)te(c.value,{itemSelector:"button"});else{const r=p.value?.querySelector("tbody tr a, tbody tr button:not([disabled])");r&&r.focus()}}return J({focusFirstElement:f}),(r,t)=>(m(),v(A,null,[n("div",{class:"permissions-section",ref_key:"orgSection",ref:U},[n("h2",null,C(L.value?"Organizations":"Your Organizations"),1),n("div",{class:"actions",ref_key:"orgActionsRef",ref:c,onKeydown:ee},[L.value?(m(),v("button",{key:0,onClick:t[0]||(t[0]=s=>r.$emit("createOrg"))},"+ Create Org")):x("",!0)],544),n("table",{class:"org-table",ref_key:"orgTableRef",ref:p,onKeydown:t[1]||(t[1]=s=>Z(s,"org"))},[n("thead",null,[n("tr",null,[t[4]||(t[4]=n("th",null,"Name",-1)),t[5]||(t[5]=n("th",null,"Roles",-1)),t[6]||(t[6]=n("th",null,"Members",-1)),L.value?(m(),v("th",mt,"Actions")):x("",!0)])]),n("tbody",null,[(m(!0),v(A,null,Q(T.value,s=>(m(),v("tr",{key:s.uuid},[n("td",null,[n("a",{href:"#org/{{o.uuid}}",onClick:Se(D=>r.$emit("openOrg",s),["prevent"])},C(s.display_name),9,ft),L.value||$.value?(m(),v("button",{key:0,onClick:D=>r.$emit("updateOrg",s),class:"icon-btn edit-org-btn","aria-label":"Rename organization",title:"Rename organization"},"✏️",8,gt)):x("",!0)]),n("td",yt,C(X(s)),1),n("td",vt,C(s.roles.reduce((D,l)=>D+l.users.length,0)),1),L.value?(m(),v("td",pt,[n("button",{onClick:D=>r.$emit("deleteOrg",s),class:"icon-btn delete-icon","aria-label":"Delete organization",title:"Delete organization"},"❌",8,ht)])):x("",!0)]))),128))])],544)],512),L.value?(m(),v("div",bt,[t[10]||(t[10]=n("h2",null,"Permissions",-1)),n("div",{class:"matrix-wrapper",ref_key:"permMatrixRef",ref:q,onKeydown:g},[n("div",wt,[n("div",{class:"perm-matrix-grid",style:ke({gridTemplateColumns:"minmax(180px, 1fr) "+T.value.map(()=>"2.2rem").join(" ")})},[t[7]||(t[7]=n("div",{class:"grid-head perm-head"},"Permission",-1)),(m(!0),v(A,null,Q(T.value,s=>(m(),v("div",{key:"head-"+s.uuid,class:"grid-head org-head",title:s.display_name},[n("span",null,C(s.display_name),1)],8,$t))),128)),(m(!0),v(A,null,Q(w.value,s=>(m(),v(A,{key:s.uuid},[n("div",{class:"perm-name",title:s.scope},[n("span",kt,C(s.display_name),1)],8,Dt),(m(!0),v(A,null,Q(T.value,D=>(m(),v("div",{key:D.uuid+"-"+s.uuid,class:"matrix-cell"},[n("input",{type:"checkbox",checked:D.permissions.includes(s.uuid),onChange:l=>r.$emit("toggleOrgPermission",D,s.uuid,l.target.checked)},null,40,St)]))),128))],64))),128))],4)]),t[8]||(t[8]=n("p",{class:"matrix-hint muted"},"Toggle which permissions each organization can grant to its members.",-1))],544),n("div",{class:"actions",ref_key:"permActionsRef",ref:N,onKeydown:u},[L.value?(m(),v("button",{key:0,onClick:t[2]||(t[2]=s=>r.$emit("openDialog","perm-create",{display_name:"",scope:"",domain:""}))},"+ Create Permission")):x("",!0)],544),n("table",{class:"org-table",ref_key:"permTableRef",ref:B,onKeydown:t[3]||(t[3]=s=>Z(s,"perm"))},[t[9]||(t[9]=n("thead",null,[n("tr",null,[n("th",{scope:"col"},"Permission"),n("th",{scope:"col"},"Domain"),n("th",{scope:"col",class:"center"},"Members"),n("th",{scope:"col",class:"center"},"Actions")])],-1)),n("tbody",null,[(m(!0),v(A,null,Q(w.value,s=>(m(),v("tr",{key:s.uuid},[n("td",Ot,[n("div",Rt,[n("span",Ct,C(s.display_name),1),n("button",{onClick:D=>r.$emit("renamePermissionDisplay",s),class:"icon-btn edit-display-btn","aria-label":"Edit permission",title:"Edit permission"},"✏️",8,At)]),n("div",Ut,[n("span",Pt,C(s.scope),1)])]),n("td",Et,C(s.domain||"—"),1),n("td",Mt,C(o.permissionSummary[s.uuid]?.userCount||0),1),n("td",qt,[n("button",{onClick:D=>r.$emit("deletePermission",s),class:"icon-btn delete-icon","aria-label":"Delete permission",title:"Delete permission"},"❌",8,Nt)])]))),128))])],544)])):x("",!0)],64))}},xt=de(Tt,[["__scopeId","data-v-ee865306"]]),Lt=["title"],Ft={class:"org-name"},It={class:"matrix-scroll"},Bt=["title"],Kt=["title"],zt=["checked","onChange"],Vt=["onDrop"],jt=["onKeydown"],Ht=["title"],Gt=["onClick"],Jt={class:"role-actions"},Yt=["onClick"],Wt=["onDragstart","onClick","onKeydown","title"],Zt={class:"name"},_t={class:"meta"},Qt=["onKeydown"],Xt=["onClick"],es={__name:"AdminOrgDetail",props:{selectedOrg:Object,permissions:Array,navigationDisabled:{type:Boolean,default:!1}},emits:["updateOrg","createRole","updateRole","deleteRole","createUserInRole","openUser","toggleRolePermission","onRoleDragOver","onRoleDrop","onUserDragStart","navigateOut"],setup(o,{expose:J,emit:G}){const S=o,F=G,U=k(null),c=k(null),p=k(null),q=I(()=>[...S.selectedOrg.roles].sort((g,u)=>{const f=g.display_name.toLowerCase(),r=u.display_name.toLowerCase();return f!==r?f.localeCompare(r):g.uuid.localeCompare(u.uuid)})),N=I(()=>{const g=new Set(S.selectedOrg.permissions||[]);return S.permissions.filter(u=>g.has(u.uuid))});function B(g,u,f){F("toggleRolePermission",g,u,f)}function T(g){if(S.navigationDisabled)return;const u=H(g);if(u){if(g.preventDefault(),u==="left"||u==="right")ue(U.value,g.target,u,{itemSelector:"button"});else if(u==="up")F("navigateOut","up");else if(u==="down"){const f=c.value?.querySelector('input[type="checkbox"]');f?f.focus():Z()}}}function w(g){if(S.navigationDisabled)return;const u=H(g);if(!u)return;const f=g.target;if(f.tagName!=="INPUT")return;g.preventDefault();const r=Array.from(c.value.querySelectorAll('input[type="checkbox"]')),t=r.indexOf(f);if(t===-1)return;const s=q.value.length,D=S.selectedOrg.permissions.length,l=Math.floor(t/s),d=t%s;let h=t;if(u==="left"&&d>0)h=t-1;else if(u==="right"&&d<s-1)h=t+1;else if(u==="up"&&l>0)h=t-s;else if(u==="down"&&l<D-1)h=t+s;else if(u==="up"&&l===0){const R=U.value?.querySelector("button");R&&R.focus();return}else if(u==="down"&&l===D-1){Z();return}h!==t&&r[h]&&r[h].focus()}function L(g){if(S.navigationDisabled)return;const u=H(g);if(!u)return;const f=g.target;if(!f.classList.contains("user-chip"))return;const r=f.closest(".user-list");if(!r)return;const t=Array.from(r.querySelectorAll(".user-chip")),s=t.indexOf(f);if(s!==-1){if(u==="up"&&s>0){g.preventDefault(),t[s-1].focus();return}else if(u==="down"&&s<t.length-1){g.preventDefault(),t[s+1].focus();return}if(u==="up"&&s===0){g.preventDefault();const l=r.closest(".role-column")?.querySelector(".role-header button");l&&l.focus();return}if(!(u==="down"&&s===t.length-1)&&(u==="left"||u==="right")){g.preventDefault();const D=Array.from(p.value?.querySelectorAll(".role-column")||[]),l=r.closest(".role-column"),d=D.indexOf(l);let h=u==="left"?d-1:d+1;if(h>=0&&h<D.length){const R=D[h],V=R.querySelectorAll(".user-chip"),M=Math.min(s,V.length-1);if(V[M])V[M].focus();else{const K=R.querySelector(".plus-btn");K&&K.focus()}}else if(u==="left"&&d===0){const R=c.value?.querySelector('input[type="checkbox"]:last-of-type');R&&R.focus()}}}}function $(g,u){if(S.navigationDisabled)return;const f=H(g);if(!f)return;const r=Array.from(p.value?.querySelectorAll(".role-column")||[]);if(f==="left"||f==="right"){g.preventDefault();const t=g.currentTarget.querySelectorAll("button:not([disabled])"),s=Array.from(t).indexOf(g.target);if(f==="left"&&s>0)t[s-1].focus();else if(f==="right"&&s<t.length-1)t[s+1].focus();else if(f==="left"&&s===0&&u>0){const l=r[u-1]?.querySelectorAll(".role-header button");l?.length&&l[l.length-1].focus()}else if(f==="right"&&s===t.length-1&&u<r.length-1){const l=r[u+1]?.querySelector(".role-header button");l&&l.focus()}}else if(f==="up"){g.preventDefault();const t=c.value?.querySelectorAll('input[type="checkbox"]');if(t?.length){const s=q.value.length,l=(S.selectedOrg.permissions.length-1)*s+u;t[l]?t[l].focus():t[t.length-1].focus()}else{const s=U.value?.querySelector("button");s&&s.focus()}}else if(f==="down"){g.preventDefault();const s=r[u]?.querySelector(".user-chip");s&&s.focus()}}function X(g,u){if(S.navigationDisabled)return;const f=H(g);if(!f)return;const r=Array.from(p.value?.querySelectorAll(".role-column")||[]);if(f==="up"){g.preventDefault();const s=r[u]?.querySelector(".role-header button");s&&s.focus()}else if(f==="left"&&u>0){g.preventDefault();const t=r[u-1],s=t?.querySelector(".empty-role button"),D=t?.querySelector(".user-chip:last-child");s?s.focus():D&&D.focus()}else if(f==="right"&&u<r.length-1){g.preventDefault();const t=r[u+1],s=t?.querySelector(".empty-role button"),D=t?.querySelector(".user-chip");s?s.focus():D&&D.focus()}}function Z(){const u=p.value?.querySelector(".role-column")?.querySelector(".role-header button");u&&u.focus()}function ee(){const g=U.value?.querySelector("button");g&&g.focus()}return J({focusFirstElement:ee}),(g,u)=>(m(),v(A,null,[n("h2",{class:"org-title",ref_key:"orgTitleRef",ref:U,onKeydown:T,title:o.selectedOrg.uuid},[n("span",Ft,C(o.selectedOrg.display_name),1),n("button",{onClick:u[0]||(u[0]=f=>g.$emit("updateOrg",o.selectedOrg)),class:"icon-btn","aria-label":"Rename organization",title:"Rename organization"},"✏️")],40,Lt),n("div",{class:"matrix-wrapper",ref_key:"permMatrixRef",ref:c,onKeydown:w},[n("div",It,[n("div",{class:"perm-matrix-grid",style:ke({gridTemplateColumns:"minmax(180px, 1fr) "+q.value.map(()=>"2.2rem").join(" ")+" 2.2rem"})},[u[5]||(u[5]=n("div",{class:"grid-head perm-head"},"Permission",-1)),(m(!0),v(A,null,Q(q.value,f=>(m(),v("div",{key:"head-"+f.uuid,class:"grid-head role-head",title:f.display_name},[n("span",null,C(f.display_name),1)],8,Bt))),128)),n("div",{class:"grid-head role-head add-role-head",title:"Add role",onClick:u[1]||(u[1]=f=>g.$emit("createRole",o.selectedOrg)),role:"button",tabindex:"0",onKeydown:u[2]||(u[2]=we(f=>g.$emit("createRole",o.selectedOrg),["enter"]))},"➕",32),(m(!0),v(A,null,Q(N.value,f=>(m(),v(A,{key:f.uuid},[n("div",{class:"perm-name",title:f.scope},C(f.display_name),9,Kt),(m(!0),v(A,null,Q(q.value,r=>(m(),v("div",{key:r.uuid+"-"+f.uuid,class:"matrix-cell"},[n("input",{type:"checkbox",checked:r.permissions.includes(f.uuid),onChange:t=>B(r,f.uuid,t.target.checked)},null,40,zt)]))),128)),u[4]||(u[4]=n("div",{class:"matrix-cell add-role-cell"},null,-1))],64))),128))],4)]),u[6]||(u[6]=n("p",{class:"matrix-hint muted"},"Toggle which permissions each role grants.",-1))],544),n("div",{class:"roles-grid",ref_key:"rolesGridRef",ref:p},[(m(!0),v(A,null,Q(q.value,(f,r)=>(m(),v("div",{key:f.uuid,class:"role-column",onDragover:u[3]||(u[3]=t=>g.$emit("onRoleDragOver",t)),onDrop:t=>g.$emit("onRoleDrop",t,o.selectedOrg,f)},[n("div",{class:"role-header",onKeydown:t=>$(t,r)},[n("strong",{class:"role-name",title:f.uuid},[n("span",null,C(f.display_name),1),n("button",{onClick:t=>g.$emit("updateRole",f),class:"icon-btn","aria-label":"Edit role",title:"Edit role"},"✏️",8,Gt)],8,Ht),n("div",Jt,[n("button",{onClick:t=>g.$emit("createUserInRole",o.selectedOrg,f),class:"plus-btn","aria-label":"Add user",title:"Add user"},"➕",8,Yt)])],40,jt),f.users.length>0?(m(),v("ul",{key:0,class:"user-list",onKeydown:L},[(m(!0),v(A,null,Q(f.users.slice().sort((t,s)=>{const D=t.display_name.toLowerCase(),l=s.display_name.toLowerCase();return D!==l?D.localeCompare(l):t.uuid.localeCompare(s.uuid)}),t=>(m(),v("li",{key:t.uuid,class:"user-chip",tabindex:"0",draggable:"true",onDragstart:s=>g.$emit("onUserDragStart",s,t,o.selectedOrg.uuid),onClick:s=>g.$emit("openUser",t),onKeydown:we(s=>g.$emit("openUser",t),["enter"]),title:t.uuid},[n("span",Zt,C(t.display_name),1),n("span",_t,C(t.last_seen?new Date(t.last_seen).toLocaleDateString():"—"),1)],40,Wt))),128))],32)):(m(),v("div",{key:1,class:"empty-role",onKeydown:t=>X(t,r)},[u[7]||(u[7]=n("p",{class:"empty-text muted"},"No members",-1)),n("button",{onClick:t=>g.$emit("deleteRole",f),class:"icon-btn delete-icon","aria-label":"Delete empty role",title:"Delete role"},"❌",8,Xt)],40,Qt))],40,Vt))),128))],512)],64))}},ts=de(es,[["__scopeId","data-v-f76fbbc3"]]),ss={class:"user-detail"},ns={key:0,class:"error small"},os=["disabled"],as={class:"section-block","data-section":"registered-passkeys"},is={class:"section-body"},rs={__name:"AdminUserDetail",props:{selectedUser:Object,userDetail:Object,selectedOrg:Object,loading:Boolean,showRegModal:Boolean,navigationDisabled:{type:Boolean,default:!1}},emits:["generateUserRegistrationLink","goOverview","openOrg","onUserNameSaved","closeRegModal","editUserName","refreshUserDetail","navigateOut"],setup(o,{expose:J,emit:G}){const S=o,F=G,U=Oe(),c=k({}),p=k(null),q=k(null),N=k(null),B=k(null),T=k(null),w=k(null),L=k(null),$=I(()=>S.showRegModal);function X(){U.showMessage(`📋 Link copied! Send it to ${S.selectedUser.display_name}.`),F("closeRegModal")}function Z(){F("editUserName",S.selectedUser)}async function ee(l){try{const d=await E(`/auth/api/admin/orgs/${S.selectedUser.org_uuid}/users/${S.selectedUser.uuid}/credentials/${l.credential_uuid}`,{method:"DELETE"});d.status==="ok"?F("onUserNameSaved"):console.error("Failed to delete credential",d)}catch(d){console.error("Delete credential error",d)}}async function g(l){const d=l?.id;if(d){c.value={...c.value,[d]:!0};try{const h=await E(`/auth/api/admin/orgs/${S.selectedUser.org_uuid}/users/${S.selectedUser.uuid}/sessions/${d}`,{method:"DELETE"});if(h.status==="ok"){if(h.current_session_terminated){sessionStorage.clear(),location.reload();return}F("refreshUserDetail"),U.showMessage("Session terminated","success",2500)}else U.showMessage(h.detail||"Failed to terminate session","error")}catch(h){console.error("Terminate session error",h),U.showMessage(h.message||"Failed to terminate session","error")}finally{const h={...c.value};delete h[d],c.value=h}}}function u(l){if($.value||S.navigationDisabled)return;const d=H(l);d&&(l.preventDefault(),d==="left"||d==="right"?ue(N.value,l.target,d,{itemSelector:".mini-btn"}):d==="up"?F("navigateOut","up"):d==="down"&&te(B.value,{itemSelector:"button"}))}function f(l){if($.value||S.navigationDisabled)return;const d=H(l);d&&(l.preventDefault(),d==="left"||d==="right"?ue(B.value,l.target,d,{itemSelector:"button"}):d==="up"?te(N.value,{itemSelector:".mini-btn"}):d==="down"&&T.value?.$el?.focus())}function r(l){$.value||S.navigationDisabled||(l==="up"?te(B.value,{itemSelector:"button"}):l==="down"&&$e(w.value?.$el,0,{itemSelector:".session-group"}))}function t(l){if(!($.value||S.navigationDisabled)){if(l==="up")T.value?.$el?.focus();else if(l==="down"){const d=L.value?.querySelector("button");d&&d.focus()}}}function s(l){if($.value||S.navigationDisabled)return;const d=H(l);d&&(l.preventDefault(),d==="up"&&$e(w.value?.$el,-1,{itemSelector:".session-group"}))}function D(){te(N.value,{itemSelector:".mini-btn"})}return J({focusFirstElement:D}),(l,d)=>(m(),v("div",ss,[n("div",{ref_key:"userInfoRef",ref:N,onKeydown:u},[o.userDetail&&!o.userDetail.error?(m(),W(st,{key:0,name:o.userDetail.display_name||o.selectedUser.display_name,visits:o.userDetail.visits,"created-at":o.userDetail.created_at,"last-seen":o.userDetail.last_seen,loading:o.loading,"org-display-name":o.userDetail.org.display_name,"role-name":o.userDetail.role,"update-endpoint":`/auth/api/admin/orgs/${o.selectedUser.org_uuid}/users/${o.selectedUser.uuid}/display-name`,onSaved:d[0]||(d[0]=h=>l.$emit("onUserNameSaved")),onEditName:Z},null,8,["name","visits","created-at","last-seen","loading","org-display-name","role-name","update-endpoint"])):x("",!0)],544),o.userDetail?.error?(m(),v("div",ns,C(o.userDetail.error),1)):x("",!0),o.userDetail&&!o.userDetail.error?(m(),v(A,{key:1},[n("div",{class:"registration-actions",ref_key:"regActionsRef",ref:B,onKeydown:f},[n("button",{class:"btn-secondary reg-token-btn",onClick:d[1]||(d[1]=h=>l.$emit("generateUserRegistrationLink",o.selectedUser)),disabled:o.loading},"Generate Registration Token",8,os),d[6]||(d[6]=n("p",{class:"matrix-hint muted"}," Generate a one-time registration link so this user can register or add another passkey. Copy the link from the dialog and send it to the user, or have the user scan the QR code on their device. ",-1))],544),n("section",as,[d[7]||(d[7]=n("div",{class:"section-header"},[n("h2",null,"Registered Passkeys")],-1)),n("div",is,[re(nt,{ref_key:"credentialListRef",ref:T,credentials:o.userDetail.credentials,"aaguid-info":o.userDetail.aaguid_info,"allow-delete":!0,"hovered-credential-uuid":p.value,"hovered-session-credential-uuid":q.value?.credential_uuid,"navigation-disabled":$.value,onDelete:ee,onCredentialHover:d[2]||(d[2]=h=>p.value=h),onNavigateOut:r},null,8,["credentials","aaguid-info","hovered-credential-uuid","hovered-session-credential-uuid","navigation-disabled"])])]),re(ot,{ref_key:"sessionListRef",ref:w,sessions:o.userDetail.sessions||[],"terminating-sessions":c.value,"hovered-credential-uuid":p.value,"navigation-disabled":$.value,"empty-message":"This user has no active sessions.","section-description":"View and manage the active sessions for this user.",onTerminate:g,onSessionHover:d[3]||(d[3]=h=>q.value=h),onNavigateOut:t},null,8,["sessions","terminating-sessions","hovered-credential-uuid","navigation-disabled"])],64)):x("",!0),n("div",{class:"actions ancillary-actions",ref_key:"backButtonRef",ref:L,onKeydown:s},[o.selectedOrg?(m(),v("button",{key:0,onClick:d[4]||(d[4]=h=>l.$emit("openOrg",o.selectedOrg)),class:"icon-btn",title:"Back to Org"},"↩️")):x("",!0)],544),o.showRegModal?(m(),W(at,{key:2,endpoint:`/auth/api/admin/orgs/${o.selectedUser.org_uuid}/users/${o.selectedUser.uuid}/create-link`,"user-name":o.userDetail?.display_name||o.selectedUser.display_name,onClose:d[5]||(d[5]=h=>l.$emit("closeRegModal")),onCopied:X},null,8,["endpoint","user-name"])):x("",!0)]))}},ls=de(rs,[["__scopeId","data-v-70289426"]]),us={class:"modal-title"},ds={key:0},cs={key:2},ms={class:"small muted"},fs=["placeholder","pattern"],gs={class:"small muted"},ys={key:7},vs={key:8,class:"error small"},ps={key:9,class:"modal-actions"},hs=["disabled"],bs=["disabled"],ws={__name:"AdminDialogs",props:{dialog:Object,PERMISSION_ID_PATTERN:String,settings:Object},emits:["submitDialog","closeDialog"],setup(o,{emit:J}){const G=o,S=new Set(["org-update","role-update","user-update-name"]),F=I(()=>G.settings?.rp_id||"the configured domain");return(U,c)=>o.dialog.type?(m(),W(it,{key:0,onClose:c[14]||(c[14]=p=>U.$emit("closeDialog"))},{default:Ye(()=>[n("h3",us,[o.dialog.type==="org-create"?(m(),v(A,{key:0},[z("Create Organization")],64)):o.dialog.type==="org-update"?(m(),v(A,{key:1},[z("Rename Organization")],64)):o.dialog.type==="role-create"?(m(),v(A,{key:2},[z("Create Role")],64)):o.dialog.type==="role-update"?(m(),v(A,{key:3},[z("Edit Role")],64)):o.dialog.type==="user-create"?(m(),v(A,{key:4},[z("Add User To Role")],64)):o.dialog.type==="user-update-name"?(m(),v(A,{key:5},[z("Edit User Name")],64)):o.dialog.type==="perm-create"||o.dialog.type==="perm-display"?(m(),v(A,{key:6},[z(C(o.dialog.type==="perm-create"?"Create Permission":"Edit Permission Display"),1)],64)):o.dialog.type==="confirm"?(m(),v(A,{key:7},[z("Confirm")],64)):x("",!0)]),n("form",{onSubmit:c[13]||(c[13]=Se(p=>U.$emit("submitDialog"),["prevent"])),class:"modal-form"},[o.dialog.type==="org-create"?(m(),v("label",ds,[c[15]||(c[15]=z("Name ",-1)),oe(n("input",{ref:"nameInput","onUpdate:modelValue":c[0]||(c[0]=p=>o.dialog.data.name=p),required:""},null,512),[[ae,o.dialog.data.name]])])):o.dialog.type==="org-update"?(m(),W(fe,{key:1,label:"Organization Name",modelValue:o.dialog.data.name,"onUpdate:modelValue":c[1]||(c[1]=p=>o.dialog.data.name=p),busy:o.dialog.busy,error:o.dialog.error,onCancel:c[2]||(c[2]=p=>U.$emit("closeDialog"))},null,8,["modelValue","busy","error"])):o.dialog.type==="role-create"?(m(),v("label",cs,[c[16]||(c[16]=z("Role Name ",-1)),oe(n("input",{"onUpdate:modelValue":c[3]||(c[3]=p=>o.dialog.data.name=p),placeholder:"Role name",required:""},null,512),[[ae,o.dialog.data.name]])])):o.dialog.type==="role-update"?(m(),W(fe,{key:3,label:"Role Name",modelValue:o.dialog.data.name,"onUpdate:modelValue":c[4]||(c[4]=p=>o.dialog.data.name=p),busy:o.dialog.busy,error:o.dialog.error,onCancel:c[5]||(c[5]=p=>U.$emit("closeDialog"))},null,8,["modelValue","busy","error"])):o.dialog.type==="user-create"?(m(),v(A,{key:4},[n("p",ms,"Role: "+C(o.dialog.data.role.display_name),1),n("label",null,[c[17]||(c[17]=z("Display Name ",-1)),oe(n("input",{"onUpdate:modelValue":c[6]||(c[6]=p=>o.dialog.data.name=p),placeholder:"User display name",required:""},null,512),[[ae,o.dialog.data.name]])])],64)):o.dialog.type==="user-update-name"?(m(),W(fe,{key:5,label:"Display Name",modelValue:o.dialog.data.name,"onUpdate:modelValue":c[7]||(c[7]=p=>o.dialog.data.name=p),busy:o.dialog.busy,error:o.dialog.error,onCancel:c[8]||(c[8]=p=>U.$emit("closeDialog"))},null,8,["modelValue","busy","error"])):o.dialog.type==="perm-create"||o.dialog.type==="perm-display"?(m(),v(A,{key:6},[n("label",null,[c[18]||(c[18]=z("Display Name ",-1)),oe(n("input",{ref:"displayNameInput","onUpdate:modelValue":c[9]||(c[9]=p=>o.dialog.data.display_name=p),required:""},null,512),[[ae,o.dialog.data.display_name]])]),n("label",null,[c[19]||(c[19]=z("Permission Scope ",-1)),oe(n("input",{"onUpdate:modelValue":c[10]||(c[10]=p=>o.dialog.data.scope=p),placeholder:o.dialog.type==="perm-create"?"yourapp:permission":o.dialog.data.permission.scope,required:"",pattern:o.PERMISSION_ID_PATTERN,title:"Allowed: A-Za-z0-9:._~-","data-form-type":"other"},null,8,fs),[[ae,o.dialog.data.scope]])]),c[21]||(c[21]=n("p",{class:"small muted"},"E.g. yourapp:reports. Changing the scope name may break deployed applications.",-1)),n("label",null,[c[20]||(c[20]=z("Domain Scope ",-1)),oe(n("input",{"onUpdate:modelValue":c[11]||(c[11]=p=>o.dialog.data.domain=p),placeholder:"e.g. app.example.com","data-form-type":"other"},null,512),[[ae,o.dialog.data.domain]])]),n("p",gs,"If set, this permission is effective only on the specified domain, which can be "+C(F.value)+" or its subdomain.",1)],64)):o.dialog.type==="confirm"?(m(),v("p",ys,C(o.dialog.data.message),1)):x("",!0),o.dialog.error&&!le(S).has(o.dialog.type)?(m(),v("div",vs,C(o.dialog.error),1)):x("",!0),le(S).has(o.dialog.type)?x("",!0):(m(),v("div",ps,[n("button",{type:"button",class:"btn-secondary",onClick:c[12]||(c[12]=p=>U.$emit("closeDialog")),disabled:o.dialog.busy}," Cancel ",8,hs),n("button",{type:"submit",class:"btn-primary",disabled:o.dialog.busy},C(o.dialog.type==="confirm"?"OK":"Save"),9,bs)]))],32)]),_:1})):x("",!0)}},$s=de(ws,[["__scopeId","data-v-4e9dba95"]]),Ds={class:"app-shell admin-shell"},ks={class:"app-main"},Ss={key:2,class:"access-denied-container"},Os={class:"access-denied-content"},Rs={key:0,class:"error-detail"},Cs={key:1,class:"error-detail"},As={class:"button-row"},Us={key:3,class:"view-root view-root--wide view-admin"},Ps={class:"view-header"},Es={class:"section-block admin-section"},Ms={class:"section-body admin-section-body"},qs={class:"admin-panels"},Ns="^[A-Za-z0-9:._~-]+$",Ts={__name:"AdminApp",setup(o){const J=k(null),G=k(!0),S=k("Loading..."),F=k(!1),U=k(!1),c=k(null),p=k([]),q=k([]),N=k(null),B=k(null),T=k(null),w=Oe(),L=k(null);k(null),k(""),k(null),k("");const $=k({type:null,data:null,busy:!1,error:""}),X=k(null),Z=k(null),ee=k(null),g=k(null),u=k(null),f=I(()=>$.value.type!==null||ce.value),r=I(()=>J.value?.permissions?.includes("auth:admin")??!1),t=I(()=>J.value?.permissions?.includes("auth:org:admin")??!1);function s(e){if(!L.value)return;const a=e.target.closest(".org-add-menu"),i=e.target.closest(".add-org-btn");!a&&!i&&(L.value=null)}We(async()=>{document.addEventListener("click",s),window.addEventListener("hashchange",d),await w.loadSettings(),w.settings?.rp_name&&(document.title=w.settings.rp_name+" Admin"),await M()}),Ze(()=>{document.removeEventListener("click",s),window.removeEventListener("hashchange",d)});const D=I(()=>{const e={};for(const i of p.value){const y={uuid:i.uuid,display_name:i.display_name},b=new Set(i.permissions||[]);for(const O of i.permissions||[])e[O]||(e[O]={orgs:[],orgSet:new Set,userCount:0}),e[O].orgSet.has(i.uuid)||(e[O].orgs.push(y),e[O].orgSet.add(i.uuid));for(const O of i.roles)for(const P of O.permissions)b.has(P)&&(e[P]||(e[P]={orgs:[],orgSet:new Set,userCount:0}),e[P].orgSet.has(i.uuid)||(e[P].orgs.push(y),e[P].orgSet.add(i.uuid)),e[P].userCount+=O.users.length)}const a={};for(const[i,y]of Object.entries(e))a[i]={orgs:y.orgs.sort((b,O)=>b.display_name.localeCompare(O.display_name)),userCount:y.userCount};return a});function l(e){_("perm-display",{permission:e,scope:e.scope,display_name:e.display_name,domain:e.domain||""})}function d(){const e=window.location.hash||"";N.value=null,B.value=null,e.startsWith("#org/")?N.value=e.slice(5):e.startsWith("#user/")&&(B.value=e.slice(6))}async function h(){const e=await E("/auth/api/admin/orgs");p.value=e.map(a=>{const i=a.roles.map(b=>({...b,org_uuid:a.uuid,users:[]})),y=Object.fromEntries(i.map(b=>[b.display_name,b]));for(const b of a.users||[])y[b.role]&&y[b.role].users.push(b);return{...a,roles:i}})}async function R(){q.value=await E("/auth/api/admin/permissions")}async function V(){J.value=await E("/auth/api/user-info",{method:"POST"}),F.value=!0}async function M(){G.value=!0,S.value="Loading...",c.value=null;try{await Promise.all([h(),R()]),await V(),!r.value&&t.value&&p.value.length===1&&(!window.location.hash||window.location.hash==="#overview")?(N.value=p.value[0].uuid,window.location.hash=`#org/${N.value}`,w.showMessage(`Navigating to ${p.value[0].display_name} Administration`,"info",3e3)):d()}catch(e){e.name==="AuthCancelledError"?U.value=!0:c.value=e.message}finally{G.value=!1}}function K(){_("org-create",{})}function ie(e){_("org-update",{org:e,name:e.display_name})}function Ce(e){_("user-update-name",{user:e,name:e.display_name})}async function ge(e){await E(`/auth/api/admin/orgs/${e}`,{method:"DELETE"}),await Promise.all([h(),R()])}function Ae(e){if(!r.value){w.showMessage("Global admin only");return}if(e.roles.reduce((b,O)=>b+O.users.length,0)===0){ge(e.uuid).then(()=>{w.showMessage(`Organization "${e.display_name}" deleted.`,"success",2500)}).catch(b=>{w.showMessage(b.message||"Failed to delete organization","error")});return}const y=e.roles.filter(b=>b.users.length>0).map(b=>`${b.users.length} ${b.display_name}`).join(", ");_("confirm",{message:`Delete organization "${e.display_name}", including accounts of ${y})?`,action:async()=>{await ge(e.uuid)}})}function Ue(e,a){_("user-create",{org:e,role:a})}async function Pe(e,a,i){if(a.role!==i)try{await E(`/auth/api/admin/orgs/${e.uuid}/users/${a.uuid}/role`,{method:"PATCH",body:{role:i}}),await h()}catch(y){w.showMessage(y.message||"Failed to update user role")}}function Ee(e,a,i){e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",JSON.stringify({user_uuid:a.uuid,org_uuid:i}))}function Me(e){e.preventDefault(),e.dataTransfer.dropEffect="move"}function qe(e,a,i){e.preventDefault();try{const y=JSON.parse(e.dataTransfer.getData("text/plain"));if(y.org_uuid!==a.uuid)return;const b=a.roles.flatMap(O=>O.users).find(O=>O.uuid===y.user_uuid);b&&Pe(a,b,i.display_name)}catch{}}function Ne(e){_("role-create",{org:e})}function Te(e){_("role-update",{role:e,name:e.display_name})}function xe(e){E(`/auth/api/admin/orgs/${e.org_uuid}/roles/${e.uuid}`,{method:"DELETE"}).then(()=>{w.showMessage(`Role "${e.display_name}" deleted.`,"success",2500),h()}).catch(a=>{w.showMessage(a.message||"Failed to delete role","error")})}async function Le(e,a,i){const y=[...e.permissions],b=i?[...e.permissions,a]:e.permissions.filter(O=>O!==a);e.permissions=b;try{const O=i?"POST":"DELETE";await E(`/auth/api/admin/orgs/${e.org_uuid}/roles/${e.uuid}/permissions/${a}`,{method:O}),await h()}catch(O){w.showMessage(O.message||"Failed to update role permission"),e.permissions=y}}async function ye(e){const a=new URLSearchParams({permission_id:e});await E(`/auth/api/admin/permission?${a.toString()}`,{method:"DELETE"}),await R()}function Fe(e){const a=D.value[e.uuid]?.userCount||0;let i=0;for(const O of p.value)for(const P of O.roles)P.permissions.includes(e.uuid)&&i++;if(i===0){ye(e.scope).then(()=>{w.showMessage(`Permission "${e.display_name}" deleted.`,"success",2500)}).catch(O=>{w.showMessage(O.message||"Failed to delete permission","error")});return}const y=[];i>0&&y.push(`${i} role${i!==1?"s":""}`),a>0&&y.push(`${a} user${a!==1?"s":""}`);const b=y.join(", ");_("confirm",{message:`Delete permission "${e.display_name}" (${b})?`,action:async()=>{await ye(e.scope)}})}function ve(){window.location.reload()}const ne=I(()=>p.value.find(e=>e.uuid===N.value)||null);function pe(e){window.location.hash=`#org/${e.uuid}`}function Ie(){window.location.hash="#overview"}function Be(e){window.location.hash=`#user/${e.uuid}`}const j=I(()=>{if(!B.value)return null;for(const e of p.value)for(const a of e.roles){const i=a.users.find(y=>y.uuid===B.value);if(i)return{...i,org_uuid:e.uuid,role_display_name:a.display_name}}return null}),Ke=I(()=>j.value?"Admin: User":ne.value?"Admin: Org":(w.settings?.rp_name||"Master")+" Admin"),ze=I(()=>{const e=[{label:"Auth",href:_e()},{label:"Admin",href:Qe()}];let a=null;j.value&&(a=p.value.find(y=>y.uuid===j.value.org_uuid)||null);const i=ne.value||a;return i&&e.push({label:i.display_name,href:`#org/${i.uuid}`}),j.value&&e.push({label:j.value.display_name||"User",href:`#user/${j.value.uuid}`}),e});Xe(j,async e=>{if(!e){T.value=null;return}try{T.value=await E(`/auth/api/admin/orgs/${e.org_uuid}/users/${e.uuid}`)}catch(a){T.value={error:a.message}}});const ce=k(!1);function Ve(e){ce.value=!0}async function je(e,a,i){const y=e.permissions.includes(a);if(i&&y||!i&&!y)return;const b=i?[...e.permissions,a]:e.permissions.filter(P=>P!==a),O=[...e.permissions];e.permissions=b;try{const P=new URLSearchParams({permission_id:a});await E(`/auth/api/admin/orgs/${e.uuid}/permission?${P.toString()}`,{method:i?"POST":"DELETE"}),await h()}catch(P){w.showMessage(P.message||"Failed to update organization permission","error"),e.permissions=O}}function _(e,a){const i=document.activeElement;if(X.value=i,e==="confirm"&&i){const y=i.closest("tr");if(y){const b=y.closest("tbody");if(b){const O=Array.from(b.querySelectorAll("tr")),P=O.indexOf(y);$.value.focusContext={tbody:b,index:P,total:O.length,selector:"button:not([disabled]), a"}}}}$.value={...$.value,type:e,data:a,busy:!1,error:""}}function Y(){const e=X.value,a=$.value.focusContext;$.value={type:null,data:null,busy:!1,error:""},He(e,a),X.value=null}function He(e,a){if(!e)return;if(document.body.contains(e)&&!e.disabled){e.focus();return}if(a?.tbody&&a.selector){const b=Array.from(a.tbody.querySelectorAll("tr"));if(b.length>0){const O=Math.min(a.index,b.length-1),se=b[O]?.querySelector(a.selector);if(se){se.focus();return}}}const i=document.querySelector(".admin-panels");if(!i)return;const y=i.querySelector('button:not([disabled]), a, input:not([disabled]), [tabindex="0"]');y&&y.focus()}function Ge(e){if(f.value)return;const a=H(e);a&&a==="down"&&(e.preventDefault(),ee.value?ee.value.focusFirstElement?.():g.value?g.value.focusFirstElement?.():u.value&&u.value.focusFirstElement?.())}function me(e){f.value||e==="up"&&Z.value?.focusCurrent?.()}async function he(){if(await h(),j.value)try{T.value=await E(`/auth/api/admin/orgs/${j.value.org_uuid}/users/${j.value.uuid}`)}catch(e){w.showMessage(e.message||"Failed to reload user","error")}}async function be(){await he(),w.showMessage("User renamed","success",1500)}async function Je(){if(!(!$.value.type||$.value.busy)){$.value.busy=!0,$.value.error="";try{const e=$.value.type;if(e==="org-create"){const a=$.value.data.name?.trim();if(!a)throw new Error("Name required");Y(),E("/auth/api/admin/orgs",{method:"POST",body:{display_name:a,permissions:[]}}).then(()=>{w.showMessage(`Organization "${a}" created.`,"success",2500),Promise.all([h(),R()])}).catch(i=>{w.showMessage(i.message||"Failed to create organization","error")});return}else if(e==="org-update"){const{org:a}=$.value.data,i=$.value.data.name?.trim();if(!i)throw new Error("Name required");Y(),E(`/auth/api/admin/orgs/${a.uuid}`,{method:"PATCH",body:{display_name:i}}).then(()=>{w.showMessage(`Organization renamed to "${i}".`,"success",2500),h()}).catch(y=>{w.showMessage(y.message||"Failed to update organization","error")});return}else if(e==="role-create"){const{org:a}=$.value.data,i=$.value.data.name?.trim();if(!i)throw new Error("Name required");Y(),E(`/auth/api/admin/orgs/${a.uuid}/roles`,{method:"POST",body:{display_name:i,permissions:[]}}).then(()=>{w.showMessage(`Role "${i}" created.`,"success",2500),h()}).catch(y=>{w.showMessage(y.message||"Failed to create role","error")});return}else if(e==="role-update"){const{role:a}=$.value.data,i=$.value.data.name?.trim();if(!i)throw new Error("Name required");Y(),E(`/auth/api/admin/orgs/${a.org_uuid}/roles/${a.uuid}`,{method:"PATCH",body:{display_name:i}}).then(()=>{w.showMessage(`Role renamed to "${i}".`,"success",2500),h()}).catch(y=>{w.showMessage(y.message||"Failed to update role","error")});return}else if(e==="user-create"){const{org:a,role:i}=$.value.data,y=$.value.data.name?.trim();if(!y)throw new Error("Name required");Y(),E(`/auth/api/admin/orgs/${a.uuid}/users`,{method:"POST",body:{display_name:y,role:i.display_name}}).then(()=>{w.showMessage(`User "${y}" added to ${i.display_name} role.`,"success",2500),h()}).catch(b=>{w.showMessage(b.message||"Failed to add user","error")});return}else if(e==="user-update-name"){const{user:a}=$.value.data,i=$.value.data.name?.trim();if(!i)throw new Error("Name required");Y(),E(`/auth/api/admin/orgs/${a.org_uuid}/users/${a.uuid}/display-name`,{method:"PATCH",body:{display_name:i}}).then(()=>{w.showMessage(`User renamed to "${i}".`,"success",2500),be()}).catch(y=>{w.showMessage(y.message||"Failed to update user name","error")});return}else if(e==="perm-display"){const{permission:a}=$.value.data,i=$.value.data.scope?.trim(),y=$.value.data.display_name?.trim(),b=$.value.data.domain?.trim()||"";if(!y)throw new Error("Display name required");if(!i)throw new Error("Scope required");Y();const O=a.domain||"";let P;if(i!==a.scope)P=E("/auth/api/admin/permission/rename",{method:"POST",body:{old_scope:a.scope,new_scope:i,display_name:y,domain:b}});else if(y!==a.display_name||b!==O){const se=new URLSearchParams({permission_id:a.scope,display_name:y});b&&se.set("domain",b),P=E(`/auth/api/admin/permission?${se.toString()}`,{method:"PATCH"})}else return;P.then(()=>{w.showMessage(`Permission "${y}" updated.`,"success",2500),R()}).catch(se=>{w.showMessage(se.message||"Failed to update permission","error")});return}else if(e==="perm-create"){const a=$.value.data.scope?.trim();if(!a)throw new Error("Scope required");const i=$.value.data.display_name?.trim();if(!i)throw new Error("Display name required");const y=$.value.data.domain?.trim()||"";Y(),E("/auth/api/admin/permissions",{method:"POST",body:{scope:a,display_name:i,domain:y||void 0}}).then(()=>{w.showMessage(`Permission "${i}" created.`,"success",2500),R()}).catch(b=>{w.showMessage(b.message||"Failed to create permission","error")});return}else if(e==="confirm"){const a=$.value.data.action;if(Y(),a)try{await a()}catch(i){w.showMessage(i.message||"Action failed","error")}return}Y()}catch(e){$.value.error=e.message||"Error"}finally{$.value.busy=!1}}}return(e,a)=>(m(),v("div",Ds,[re(rt),n("main",ks,[G.value?(m(),W(lt,{key:0,message:S.value},null,8,["message"])):U.value?(m(),W(ut,{key:1,onReload:ve})):c.value||F.value&&!r.value&&!t.value?(m(),v("div",Ss,[n("div",Os,[a[2]||(a[2]=n("h2",null,"⛔ Access Denied",-1)),c.value?(m(),v("p",Rs,C(c.value),1)):(m(),v("p",Cs,"You do not have admin permissions for this application.")),n("div",As,[n("button",{class:"btn-secondary",onClick:a[0]||(a[0]=(...i)=>le(De)&&le(De)(...i))},"Back"),n("button",{class:"btn-primary",onClick:ve},"Reload Page")])])])):F.value&&(r.value||t.value)?(m(),v("section",Us,[n("header",Ps,[n("h1",null,C(Ke.value),1),re(dt,{ref_key:"breadcrumbsRef",ref:Z,entries:ze.value,onKeydown:Ge},null,8,["entries"])]),n("section",Es,[n("div",Ms,[n("div",qs,[!j.value&&!ne.value&&(r.value||t.value)?(m(),W(xt,{key:0,ref_key:"adminOverviewRef",ref:ee,info:J.value,orgs:p.value,permissions:q.value,"navigation-disabled":f.value,"permission-summary":D.value,onCreateOrg:K,onOpenOrg:pe,onUpdateOrg:ie,onDeleteOrg:Ae,onToggleOrgPermission:je,onOpenDialog:_,onDeletePermission:Fe,onRenamePermissionDisplay:l,onNavigateOut:me},null,8,["info","orgs","permissions","navigation-disabled","permission-summary"])):j.value?(m(),W(ls,{key:1,ref_key:"adminUserDetailRef",ref:u,"selected-user":j.value,"user-detail":T.value,"selected-org":ne.value,loading:G.value,"show-reg-modal":ce.value,"navigation-disabled":f.value,onGenerateUserRegistrationLink:Ve,onGoOverview:Ie,onOpenOrg:pe,onOnUserNameSaved:be,onRefreshUserDetail:he,onEditUserName:Ce,onCloseRegModal:a[1]||(a[1]=i=>ce.value=!1),onNavigateOut:me},null,8,["selected-user","user-detail","selected-org","loading","show-reg-modal","navigation-disabled"])):ne.value?(m(),W(ts,{key:2,ref_key:"adminOrgDetailRef",ref:g,"selected-org":ne.value,permissions:q.value,"navigation-disabled":f.value,onUpdateOrg:ie,onCreateRole:Ne,onUpdateRole:Te,onDeleteRole:xe,onCreateUserInRole:Ue,onOpenUser:Be,onToggleRolePermission:Le,onOnRoleDragOver:Me,onNavigateOut:me,onOnRoleDrop:qe,onOnUserDragStart:Ee},null,8,["selected-org","permissions","navigation-disabled"])):x("",!0)])])])])):x("",!0)]),re($s,{dialog:$.value,"permission-id-pattern":Ns,settings:le(w).settings,onSubmitDialog:Je,onCloseDialog:Y},null,8,["dialog","settings"])]))}},xs=de(Ts,[["__scopeId","data-v-17f9d23b"]]),Re=et(xs);Re.use(ct());Re.mount("#admin-app");tt();
@@ -1 +0,0 @@
1
- import{_ as Me,r as d,w as Ze,c as L,o as Ee,n as ye,a as Be,b as w,d as v,e as a,f as V,g as $e,h as lt,F as de,i as rt,j as Le,t as A,k as F,v as it,l as Je,m as ut,s as ct,p as dt,q as ft,u as vt,x as ae,y as G,z as C,A as Ke,B as fe,C as Ae,D as we,E as We,G as ht,H as Pe,I as pt,J as gt,K as mt}from"./_plugin-vue_export-helper-rKFEraYH.js";import{u as _e,B as yt,U as Ge,_ as wt,a as bt,N as _t,M as kt,R as It,L as St,b as xt,A as Ct,c as $t}from"./AccessDenied-aTdCvz9k.js";import{i as Fe,a as ee,g as je,b as qe,c as Oe,s as Ye}from"./pow-2N9bxgAo.js";import{g as be}from"./helpers-DzjFIx78.js";const Lt={class:"pairing-entry"},At={key:0,class:"input-row"},Wt={class:"slot-word"},Pt={class:"typed-prefix"},Mt={class:"hint-suffix"},Et={key:0,class:"cursor-overlay",style:{"--cursor-pos":0,"--word-len":0}},Bt=["placeholder"],Dt={key:0,class:"processing-status"},Nt={class:"processing-icon"},Tt={key:1,class:"device-info"},Vt={class:"device-permit-text"},Ut={class:"device-meta"},Rt={key:0,class:"error-message",style:{"margin-top":"0.5rem"}},zt={class:"button-row",style:{"margin-top":"0.75rem",display:"flex",gap:"0.5rem"}},Ht=["disabled"],Kt=["disabled"],Ft={__name:"RemoteAuthPermit",props:{title:{type:String,default:"Help Another Device Sign In"},description:{type:String,default:"Enter the code shown on the device that needs to sign in."},placeholder:{type:String,default:"Enter three words"},action:{type:String,default:"login"}},emits:["completed","error","cancelled","back","register","deviceInfoVisible"],setup(le,{expose:o,emit:E}){const W=E,_=d(!1),b=d(null),N=d(null);let f=null,T=null;try{T=_e()}catch{}const k=d(null),z=d(null),u=d(""),P=d(!1),B=d(""),g=d(null),h=d("");Ze(g,e=>{W("deviceInfoVisible",!!e)});const p=d(!1),I=d(!1),c=d(0),$=d(0),U=d(0),Q=d(!1),ve=d(!1);let te=0,se=!1,Z=null,ne=null,j=null,q=null,R=null,J=null;function oe(e,s="info",t=3e3){T&&T.showMessage(e,s,t)}async function re(){try{const e=await ut();N.value=e}catch(e){console.warn("Unable to load settings",e)}}function ie(e,s){if(!e||s<0)return{word:"",start:0,end:0};let t=s,i=s;for(;t>0&&/[a-zA-Z]/.test(e[t-1]);)t--;for(;i<e.length&&/[a-zA-Z]/.test(e[i]);)i++;return{word:e.slice(t,i),start:t,end:i}}function X(e){return e.trim().split(/[.\s]+/).filter(s=>s.length>0)}function D(e){const s=X(e),t=[];for(const i of s){let r=i.toLowerCase();for(;r.length>0&&t.length<3;){let x=null;for(let y=Math.min(r.length,6);y>=3;y--){const S=r.slice(0,y);if(ee(S)){x=S;break}}if(x)t.push(x),r=r.slice(x.length);else{t.push(r);break}}if(t.length>=3)break}return t}function he(e){const s=/[.\s]$/.test(e),t=D(e);return s?t.length:Math.max(0,t.length-1)}function pe(e){if(!e)return{valid:!0,segments:[]};const s=[],t=/[.\s]$/.test(e);let i,r=/([a-zA-Z]+)|([.\s]+)/g;for(;(i=r.exec(e))!==null;)i[1]?s.push({text:i[1],isWord:!0,start:i.index}):i[2]&&s.push({text:i[2],isWord:!1,start:i.index});const x=s.filter(S=>S.isWord);let y=!0;return x.forEach((S,H)=>{const M=H===x.length-1,Y=S.text.toLowerCase();M&&!t?S.invalid=!Fe(Y):S.invalid=!ee(Y),S.invalid&&(y=!1)}),{valid:y,segments:s}}L(()=>{const{segments:e}=pe(u.value);return e.map(s=>({text:s.text,invalid:s.invalid||!1}))});function ke(e){return pe(e).valid}function Ie(e){return D(e).length>0&&D(e).every(s=>ee(s))}function ge(e){if(/[.\s]$/.test(e))return"";const t=e.match(/[a-zA-Z]+$/);return t?t[0].toLowerCase():""}function Se(e,s){if(!e||s===0)return{wordIndex:0,charIndex:0};const t=e.slice(0,s),i=/[.\s]$/.test(t),r=D(t);if(r.length===0)return{wordIndex:0,charIndex:0};if(i)return{wordIndex:Math.min(r.length,2),charIndex:0};const x=r[r.length-1],y=r.length-1;D(e);const S=x.length;return y<2&&!ve.value&&ee(x)?{wordIndex:y+1,charIndex:0}:{wordIndex:Math.min(y,2),charIndex:S}}function ue(e,s){if(!e||s===0)return{wordIndex:0,charIndex:0};const t=e.slice(0,s),i=/[.\s]$/.test(t),r=D(t);if(r.length===0)return{wordIndex:0,charIndex:0};if(i)return{wordIndex:Math.min(r.length,2),charIndex:0};const x=r[r.length-1],y=r.length-1;return{wordIndex:Math.min(y,2),charIndex:x.length}}const l=L(()=>{const e=D(u.value),s=[],t=ge(u.value),i=h.value,r=/[.\s]$/.test(u.value),x=$.value!==U.value,y=ue(u.value,Math.min($.value,U.value)),S=ue(u.value,Math.max($.value,U.value)),H=x?ue(u.value,c.value):Se(u.value,c.value);for(let M=0;M<3;M++){const Y=H.wordIndex===M;let O=-1,K=-1;if(x&&(M>y.wordIndex&&M<S.wordIndex?(O=0,K=e[M]?.length??0):M===y.wordIndex&&M===S.wordIndex?(O=y.charIndex,K=S.charIndex):M===y.wordIndex?(O=y.charIndex,K=e[M]?.length??0):M===S.wordIndex&&(O=0,K=S.charIndex)),M<e.length){const me=e[M].toLowerCase(),ze=M===e.length-1,He=ze&&!r?!Fe(me):!ee(me);if(ze&&!r&&i&&t){const at=i.length;s.push({text:"",typedPrefix:t,hintSuffix:i.slice(t.length),invalid:He,hasCursor:Y,cursorCharIndex:Y?H.charIndex:-1,wordLen:at,selectionStartChar:O,selectionEndChar:K})}else s.push({text:me,invalid:He,hasCursor:Y,cursorCharIndex:Y?H.charIndex:-1,wordLen:me.length,selectionStartChar:O,selectionEndChar:K})}else s.push({text:"",invalid:!1,hasCursor:Y,cursorCharIndex:0,wordLen:0,selectionStartChar:O,selectionEndChar:K})}return s}),n=L(()=>$.value!==U.value),m=L(()=>{const e=D(u.value);return e.length===3&&e.every(s=>ee(s))});function De(e){return D(e).join(".")}function Xe(){if(!Z||j)return;const e=Oe(Z);j=Ye(e,ne).then(s=>{q=s,j=null})}async function Ne(){if(q){const s=q;return q=null,s}if(j){await j;const s=q;return q=null,s}if(!Z)throw new Error("No PoW challenge available");const e=Oe(Z);return await Ye(e,ne)}function Te(e){e?.challenge&&(Z=e.challenge,ne=e.work,q=null,j=null,Xe())}async function xe(){if(!(f||se)){se=!0;try{const e=N.value?.auth_host,s="/auth/ws/remote-auth/permit",t=e&&location.host!==e?`//${e}${s}`:s;f=await dt(t);const i=await f.receive_json();if(i.status&&i.detail)throw new Error(i.detail);if(!i.pow?.challenge)throw new Error("Server did not send PoW challenge");Te(i.pow)}catch(e){throw console.error("WebSocket connection error:",e),f=null,e}finally{se=!1}}}function et(e){if(e.key==="Tab"||e.key===" "||e.key==="Escape"){nt(e);return}setTimeout(Ve,0)}function Ve(){const e=k.value,s=e?.selectionStart??u.value.length,t=e?.selectionEnd??s,r=(e?.selectionDirection??"none")==="backward"?s:t;ve.value=r<te,te=r,c.value=r,U.value=t,$.value=s}function tt(){c.value=k.value?.selectionStart??u.value.length;const{word:e,end:s}=ie(u.value,c.value);if(he(u.value)>=3||!e||e.length<1||c.value!==s){h.value="";return}const i=je(e.toLowerCase());i&&i!==e.toLowerCase()?h.value=i:h.value=""}function Ue(){if(!h.value)return!1;const{word:e,start:s,end:t}=ie(u.value,c.value);if(!e)return!1;const i=u.value.slice(0,s),y=D(i).length===2?"":" ",S=u.value.slice(t);u.value=i+h.value+y+S.trimStart();const H=s+h.value.length+y.length;return ye(()=>{k.value?.setSelectionRange(H,H),c.value=H}),h.value="",!0}function ce(){c.value=k.value?.selectionStart??u.value.length;const e=c.value,t=u.value.slice(0,e).match(/([a-zA-Z]+) $/);if(t){const r=t[1].toLowerCase(),x=je(r);if(x&&x!==r&&!ee(r)){const y=e-t[0].length,S=u.value.slice(0,y),H=u.value.slice(e),O=D(S).length===2?"":" ";u.value=S+x+O+H;const K=y+x.length+O.length;ye(()=>{k.value?.setSelectionRange(K,K),c.value=K})}}tt(),R&&(clearTimeout(R),R=null),g.value=null,b.value=null,I.value=!1,p.value=!ke(u.value);const i=D(u.value);if(i.length>=1&&!f&&!se&&xe(),i.length===3){if(!Ie(u.value))return;R=setTimeout(()=>{st()},150)}}async function st(){if(!(P.value||_.value||!m.value||De(u.value)===J&&g.value)){P.value=!0,B.value="pow",b.value=null,I.value=!1;try{if(await xe(),!f)throw new Error("Failed to connect");const s=await Ne(),t=qe(s),i=De(u.value);if(!m.value)return;B.value="server",f.send_json({code:i,pow:t});const r=await f.receive_json();if(Te(r.pow),typeof r.status=="number"&&r.status>=400){oe(r.detail||"Request failed","error"),I.value=!0,g.value=null,J=null;return}r.status==="found"&&r.host?(g.value={host:r.host,user_agent_pretty:r.user_agent_pretty,client_ip:r.client_ip,action:r.action||"login"},J=i,ye(()=>{z.value?.focus()})):(oe("Unexpected response from server","error"),I.value=!0,g.value=null,J=null)}catch(s){console.error("Lookup error:",s),oe(s.message||"Lookup failed","error"),I.value=!0,g.value=null,J=null,f&&(f.close(),f=null)}finally{P.value=!1,B.value=""}}}function nt(e){if(e.key==="Escape"){u.value="",ce(),e.preventDefault();return}if(e.key==="Tab"){if(h.value&&Ue()){e.preventDefault(),ce();return}u.value.trim()&&e.preventDefault();return}e.key===" "&&h.value&&Ue()&&(e.preventDefault(),ce())}async function ot(){if(!(!g.value||_.value)){_.value=!0,b.value=null;try{if(f||await xe(),!f)throw new Error("Failed to connect");const e=await Ne(),s=qe(e);f.send_json({authenticate:!0,pow:s});const t=await f.receive_json();if(typeof t.status=="number"&&t.status>=400)throw new Error(t.detail||"Authentication failed");if(!t.optionsJSON)throw new Error(t.detail||"Failed to get authentication options");const i=await ct(t);f.send_json(i);const r=await f.receive_json();if(typeof r.status=="number"&&r.status>=400)throw new Error(r.detail||"Authentication failed");if(r.status==="success")oe("Device authenticated successfully!","success",3e3),W("completed"),Ce();else throw new Error(r.detail||"Authentication failed")}catch(e){console.error("Pairing error:",e);const s=e.name==="NotAllowedError"?"Passkey authentication was cancelled":e.message||"Authentication failed";b.value=s,W("error",s)}finally{_.value=!1,f&&(f.close(),f=null)}}}async function Re(){if(f){try{f.send_json({deny:!0}),await new Promise(e=>setTimeout(e,100))}catch(e){console.error("Error sending deny message:",e)}f.close(),f=null}Ce()}function Ce(){u.value="",b.value=null,I.value=!1,g.value=null,P.value=!1,B.value="",h.value="",p.value=!1,J=null,f&&(f.close(),f=null),Z=null,ne=null,j=null,q=null}return Ee(async()=>{await re(),ye(()=>{c.value=k.value?.selectionStart??0})}),Be(()=>{R&&(clearTimeout(R),R=null),f&&(f.close(),f=null)}),o({reset:Ce,deny:Re,code:u,handleInput:ce,loading:_,error:b}),(e,s)=>(v(),w("div",Lt,[a("form",{onSubmit:Je(ot,["prevent"]),class:"pairing-form"},[g.value?g.value?(v(),w("div",Tt,[a("p",Vt,[F("Permit "+A(g.value.action==="register"?"registration":"login")+" to ",1),a("strong",null,A(g.value.host),1)]),a("p",Ut,A(g.value.user_agent_pretty),1),b.value?(v(),w("p",Rt,A(b.value),1)):V("",!0),a("div",zt,[a("button",{type:"button",class:"btn-secondary",disabled:_.value,onClick:Re,style:{flex:"1"}}," Deny ",8,Ht),a("button",{ref_key:"submitBtnRef",ref:z,type:"submit",disabled:_.value,class:"btn-primary",style:{flex:"1"}},A(_.value?"Authenticating…":"Authorize"),9,Kt)])])):V("",!0):(v(),w("div",At,[a("div",{class:$e(["input-wrapper",{"has-error":I.value,"is-complete":g.value&&!I.value,focused:Q.value,"has-selection":n.value}])},[a("div",{class:$e(["slot-machine",{"has-error":I.value,"is-complete":g.value&&!I.value}]),"aria-hidden":"true"},[(v(!0),w(de,null,rt(l.value,(t,i)=>(v(),w("div",{key:i,class:$e(["slot-reel",{"invalid-word":t.invalid,empty:!t.text&&!t.typedPrefix}])},[a("div",Wt,[t.selectionStartChar>=0&&t.selectionEndChar>t.selectionStartChar?(v(),w("span",{key:0,class:"selection-overlay",style:Le({"--sel-start":t.selectionStartChar,"--sel-end":t.selectionEndChar,"--word-len":t.wordLen})},null,4)):V("",!0),t.typedPrefix?(v(),w(de,{key:1},[a("span",Pt,A(t.typedPrefix),1),a("span",Mt,A(t.hintSuffix),1),t.hasCursor?(v(),w("span",{key:0,class:"cursor-overlay",style:Le({"--cursor-pos":t.cursorCharIndex,"--word-len":t.wordLen})},null,4)):V("",!0)],64)):t.text?(v(),w(de,{key:2},[F(A(t.text)+" ",1),t.hasCursor?(v(),w("span",{key:0,class:"cursor-overlay",style:Le({"--cursor-pos":t.cursorCharIndex,"--word-len":t.wordLen})},null,4)):V("",!0)],64)):(v(),w(de,{key:3},[t.hasCursor?(v(),w("span",Et)):V("",!0)],64))])],2))),128))],2),lt(a("input",{ref_key:"inputRef",ref:k,"onUpdate:modelValue":s[0]||(s[0]=t=>u.value=t),type:"text",placeholder:le.placeholder,autocomplete:"off",autocapitalize:"none",autocorrect:"off",spellcheck:"false",class:"pairing-input hidden-input",onInput:ce,onKeydown:et,onMouseup:Ve,onFocus:s[1]||(s[1]=t=>Q.value=!0),onBlur:s[2]||(s[2]=t=>Q.value=!1)},null,40,Bt),[[it,u.value]])],2),B.value?(v(),w("div",Dt,[a("span",Nt,A(B.value==="pow"?"🔐":"📡"),1),s[3]||(s[3]=a("span",{class:"processing-spinner-small"},null,-1))])):V("",!0)]))],32)]))}},jt=Me(Ft,[["__scopeId","data-v-77a073d9"]]),qt={class:"view-root","data-view":"profile"},Ot={class:"view-header"},Yt={class:"remote-auth-inline"},Zt={key:0,class:"remote-auth-label"},Jt={class:"section-block"},Gt={class:"section-body"},Qt={class:"section-block"},Xt=["disabled"],es=["disabled"],ts=["disabled"],ss={key:0,class:"logout-note"},ns={key:1,class:"logout-note"},os={__name:"ProfileView",setup(le){const o=_e(),E=d(null),W=d(!1),_=d(!1),b=d(""),N=d(!1),f=d(null),T=d(null),k=d(!1),z=d(null),u=d(null),P=d(null),B=d(null),g=d(null),h=d(null),p=d(null),I=d(null),c=L(()=>W.value||_.value);Ze(W,l=>{l&&(b.value=o.userInfo?.user?.user_name||"")}),Ee(()=>{E.value=setInterval(()=>{o.userInfo&&(o.userInfo={...o.userInfo})},6e4)}),Be(()=>{E.value&&clearInterval(E.value)});const $=async()=>{try{await ht.register(null,null,()=>{o.showMessage("Adding new passkey...","info")}),await o.loadUserInfo(),o.showMessage("New passkey added successfully!","success",3e3)}catch(l){console.error("Failed to add new passkey:",l),o.showMessage(l.message,"error")}},U=()=>{o.showMessage("The other device is now signed in!","success",4e3),setTimeout(()=>z.value?.reset(),3e3)},Q=l=>{l.includes("cancelled")||o.showMessage(l,"error",4e3)},ve=()=>{o.showMessage("📋 Link copied! Send it to your other device."),_.value=!1},te=l=>{Ae(l,{primarySelector:".btn-primary",itemSelector:"button"})},se=l=>{if(c.value)return;const n=fe(l);n&&n==="down"&&(l.preventDefault(),Ae(I.value,{primarySelector:".mini-btn",itemSelector:".mini-btn, .pairing-input"}))},Z=l=>{if(c.value)return;const n=fe(l);if(!n)return;l.preventDefault(),n==="left"||n==="right"?we(I.value,l.target,n,{itemSelector:".mini-btn, .pairing-input"}):n==="up"?h.value?.focusCurrent?.():n==="down"&&u.value?.$el?.focus()},ne=l=>{c.value||(l==="down"||l==="right"?te(P.value):(l==="up"||l==="left")&&Ae(I.value,{primarySelector:".mini-btn",itemSelector:".mini-btn, .pairing-input"}))},j=l=>{if(c.value)return;const n=fe(l);n&&(l.preventDefault(),n==="left"||n==="right"?we(P.value,l.target,n,{itemSelector:"button"}):n==="up"?We(u.value?.$el,0,{itemSelector:".credential-item"}):n==="down"&&We(B.value?.$el,0,{itemSelector:".session-group"}))},q=l=>{c.value||(l==="up"?te(P.value):l==="down"&&te(g.value))},R=l=>{if(c.value)return;const n=fe(l);n&&(l.preventDefault(),n==="left"||n==="right"?we(g.value,l.target,n,{itemSelector:"button"}):n==="up"&&We(B.value?.$el,-1,{itemSelector:".session-group"}))},J=async l=>{const n=l?.credential_uuid;if(n)try{await o.deleteCredential(n),o.showMessage("Passkey deleted! You should also remove it from your password manager or device.","success",3e3)}catch(m){o.showMessage(`Failed to delete passkey: ${m.message}`,"error")}},oe=L(()=>o.settings?.rp_name||"this service"),re=L(()=>o.userInfo?.sessions||[]),ie=L(()=>re.value.find(n=>n.is_current)?.host||"this host"),X=d({}),D=async l=>{const n=l?.id;if(n){X.value={...X.value,[n]:!0};try{await o.terminateSession(n)}catch(m){o.showMessage(m.message||"Failed to terminate session","error",5e3)}finally{const m={...X.value};delete m[n],X.value=m}}},he=async()=>{await o.logoutEverywhere()},pe=async()=>{await o.logout()},ke=()=>{b.value=o.userInfo?.user?.user_name||"",W.value=!0},Ie=L(()=>{const l=o.userInfo?.permissions??[];return l.includes("auth:admin")||l.includes("auth:org:admin")}),ge=L(()=>re.value.length>1),Se=L(()=>{const l=[{label:"Auth",href:ft()}];return Ie.value&&l.push({label:"Admin",href:vt()}),l}),ue=async()=>{const l=b.value.trim();if(!l){o.showMessage("Name cannot be empty","error");return}try{N.value=!0,await Pe("/auth/api/user/display-name",{method:"PATCH",body:{display_name:l}}),W.value=!1,await o.loadUserInfo(),o.showMessage("Name updated successfully!","success",3e3)}catch(n){o.showMessage(n.message||"Failed to update name","error")}finally{N.value=!1}};return(l,n)=>(v(),w("section",qt,[a("header",Ot,[n[10]||(n[10]=a("h1",null,"User Profile",-1)),ae(yt,{ref_key:"breadcrumbs",ref:h,entries:Se.value,onKeydown:se},null,8,["entries"]),n[11]||(n[11]=a("p",{class:"view-lede"},"Account dashboard for managing credentials and authenticating with other devices.",-1))]),a("section",{class:"section-block",ref_key:"userInfoSection",ref:I},[C(o).userInfo?.user?(v(),G(Ge,{key:0,ref_key:"userBasicInfo",ref:p,name:C(o).userInfo.user.user_name,visits:C(o).userInfo.user.visits||0,"created-at":C(o).userInfo.user.created_at,"last-seen":C(o).userInfo.user.last_seen,loading:C(o).isLoading,"update-endpoint":"/auth/api/user/display-name",onSaved:n[1]||(n[1]=m=>C(o).loadUserInfo()),onEditName:ke,onKeydown:Z},{default:Ke(()=>[a("div",Yt,[k.value?V("",!0):(v(),w("label",Zt,"Code words:")),ae(jt,{ref_key:"pairingEntry",ref:z,title:"",description:"",onCompleted:U,onError:Q,onDeviceInfoVisible:n[0]||(n[0]=m=>k.value=m)},null,512)]),n[12]||(n[12]=a("p",{class:"remote-auth-description"},"Provided by another device requesting remote auth.",-1))]),_:1},8,["name","visits","created-at","last-seen","loading"])):V("",!0)],512),a("section",Jt,[n[13]||(n[13]=a("div",{class:"section-header"},[a("h2",null,"Your Passkeys"),a("p",{class:"section-description"},[F("Ideally have at least two passkeys in case you lose one. More than one user can be registered on the same device, giving you a choice at login. "),a("a",{href:"https://bitwarden.com/pricing/",target:"_blank",rel:"noopener noreferrer"},"Bitwarden"),F(" can sync one passkey to all your devices. Other secure options include "),a("b",null,"local passkeys"),F(", as well as hardware keys such as "),a("a",{href:"https://www.yubico.com",target:"_blank",rel:"noopener noreferrer"},"YubiKey"),F(". Cloud sync via Google, Microsoft or iCloud is discouraged.")])],-1)),a("div",Gt,[ae(wt,{ref_key:"credentialList",ref:u,credentials:C(o).userInfo?.credentials||[],"aaguid-info":C(o).userInfo?.aaguid_info||{},loading:C(o).isLoading,"hovered-credential-uuid":f.value,"hovered-session-credential-uuid":T.value?.credential_uuid,"navigation-disabled":c.value,"allow-delete":"",onDelete:J,onCredentialHover:n[2]||(n[2]=m=>f.value=m),onNavigateOut:ne},null,8,["credentials","aaguid-info","loading","hovered-credential-uuid","hovered-session-credential-uuid","navigation-disabled"]),a("div",{class:"button-row",ref_key:"credentialButtons",ref:P},[a("button",{onClick:$,class:"btn-primary",onKeydown:j},"Register New",32),a("button",{onClick:n[3]||(n[3]=m=>_.value=!0),class:"btn-secondary",onKeydown:j},"Another Device",32)],512)])]),ae(bt,{ref_key:"sessionList",ref:B,sessions:re.value,"terminating-sessions":X.value,"hovered-credential-uuid":f.value,"navigation-disabled":c.value,onTerminate:D,onSessionHover:n[4]||(n[4]=m=>T.value=m),onNavigateOut:q,"section-description":"You are currently signed in to the following sessions. If you don't recognize something, consider deleting not only the session but the associated passkey you suspect is compromised, as only this terminates all linked sessions and prevents logging in again."},null,8,["sessions","terminating-sessions","hovered-credential-uuid","navigation-disabled"]),W.value?(v(),G(kt,{key:0,onClose:n[7]||(n[7]=m=>W.value=!1)},{default:Ke(()=>[n[14]||(n[14]=a("h3",null,"Edit Display Name",-1)),a("form",{onSubmit:Je(ue,["prevent"]),class:"modal-form"},[ae(_t,{label:"Display Name",modelValue:b.value,"onUpdate:modelValue":n[5]||(n[5]=m=>b.value=m),busy:N.value,onCancel:n[6]||(n[6]=m=>W.value=!1)},null,8,["modelValue","busy"])],32)]),_:1})):V("",!0),a("section",Qt,[a("div",{class:"button-row",ref_key:"logoutButtons",ref:g},[a("button",{type:"button",class:"btn-secondary",onClick:n[8]||(n[8]=(...m)=>C(be)&&C(be)(...m)),onKeydown:R}," Back ",32),ge.value?(v(),w(de,{key:1},[a("button",{onClick:pe,class:"btn-danger",disabled:C(o).isLoading,onKeydown:R},"Logout",40,es),a("button",{onClick:he,class:"btn-danger",disabled:C(o).isLoading,onKeydown:R},"All",40,ts)],64)):(v(),w("button",{key:0,onClick:he,class:"btn-danger",disabled:C(o).isLoading,onKeydown:R},"Logout",40,Xt))],512),ge.value?(v(),w("p",ns,[n[16]||(n[16]=a("strong",null,"Logout",-1)),F(" this session on "+A(ie.value)+", or ",1),n[17]||(n[17]=a("strong",null,"All",-1)),F(" sessions across all sites and devices for "+A(oe.value)+". You'll need to log in again with your passkey afterwards.",1)])):(v(),w("p",ss,[n[15]||(n[15]=a("strong",null,"Logout",-1)),F(" from "+A(ie.value)+".",1)]))]),_.value?(v(),G(It,{key:1,endpoint:"/auth/api/user/create-link",onClose:n[9]||(n[9]=m=>_.value=!1),onCopied:ve})):V("",!0)]))}},as=Me(os,[["__scopeId","data-v-4eb8b156"]]),ls={class:"view-root host-view","data-view":"host-profile"},rs={class:"view-header"},is={class:"view-lede"},us={class:"section-body"},cs={key:1,class:"empty-state"},ds={class:"section-block"},fs={class:"section-body host-actions"},vs=["disabled"],hs=["disabled"],ps={class:"note"},gs={__name:"HostProfileView",props:{initializing:{type:Boolean,default:!1}},setup(le){const o=_e(),E=window.location.host,W=d(null),_=d(null),b=L(()=>o.userInfo?.user||null),N=L(()=>o.userInfo?.org?.display_name||""),f=L(()=>o.userInfo?.role?.display_name||""),T=L(()=>{const h=o.settings?.rp_name;return h?`${h} account`:"Account overview"}),k=L(()=>`You're signed in to ${E}.`),z=L(()=>o.settings?.auth_host||""),u=L(()=>{const h=z.value;if(!h)return"";let p=o.settings?.ui_base_path??"/auth/";return p.startsWith("/")||(p=`/${p}`),p.endsWith("/")||(p=`${p}/`),`${window.location.protocol||"https:"}//${h}${p}`}),P=()=>{u.value&&(window.location.href=u.value)},B=async()=>{await o.logout()},g=h=>{const p=fe(h);p&&(h.preventDefault(),(p==="left"||p==="right")&&we(_.value,h.target,p,{itemSelector:"button"}))};return(h,p)=>(v(),w("section",ls,[a("header",rs,[a("h1",null,A(T.value),1),a("p",is,A(k.value),1)]),a("section",{class:"section-block",ref_key:"userInfoSection",ref:W},[a("div",us,[b.value?(v(),G(Ge,{key:0,name:b.value.user_name,visits:b.value.visits||0,"created-at":b.value.created_at,"last-seen":b.value.last_seen,"org-display-name":N.value,"role-name":f.value,"can-edit":!1},null,8,["name","visits","created-at","last-seen","org-display-name","role-name"])):(v(),w("p",cs,A(le.initializing?"Loading your account…":"No active session found."),1))])],512),a("section",ds,[a("div",fs,[a("div",{class:"button-row",ref_key:"buttonRow",ref:_,onKeydown:g},[a("button",{type:"button",class:"btn-secondary",onClick:p[0]||(p[0]=(...I)=>C(be)&&C(be)(...I))}," Back "),a("button",{type:"button",class:"btn-danger",disabled:C(o).isLoading,onClick:B},A(C(o).isLoading?"Signing out…":"Logout"),9,vs),u.value?(v(),w("button",{key:0,type:"button",class:"btn-primary",disabled:C(o).isLoading,onClick:P}," Full Profile ",8,hs)):V("",!0)],544),a("p",ps,[p[1]||(p[1]=a("strong",null,"Logout",-1)),F(" from "+A(C(E))+", or access your ",1),p[2]||(p[2]=a("strong",null,"Full Profile",-1)),F(" at "+A(z.value)+" (you may need to sign in again).",1)])])])]))}},ms=Me(gs,[["__scopeId","data-v-054244d9"]]),ys={class:"app-shell"},ws={class:"app-main"},bs={__name:"App",setup(le){const o=_e(),E=d(!0),W=d("Loading..."),_=d(!1),b=d(!1);function N(c){if(!c)return null;const $=c.trim().toLowerCase();return $?$.replace(/:80$/,"").replace(/:443$/,""):null}const f=L(()=>{const c=o.settings?.auth_host;if(!c)return!1;const $=N(window.location.host),U=N(c);return $!==U});let T=null,k=null;async function z(){try{return o.userInfo=await Pe("/auth/api/user-info",{method:"POST"}),_.value=!0,E.value=!1,p(),!0}catch{return!1}}async function u(){P();const c=await pt("login");k=document.createElement("iframe"),k.id="auth-iframe",k.title="Authentication",k.allow="publickey-credentials-get; publickey-credentials-create",k.src=c,document.body.appendChild(k),W.value="Authentication required..."}function P(){k&&(k.remove(),k=null)}function B(){window.location.reload()}function g(c){const $=c.data;if($?.type)switch($.type){case"auth-success":P(),E.value=!0,W.value="Loading user profile...",z();break;case"auth-error":$.cancelled?console.log("Authentication cancelled by user"):o.showMessage($.message||"Authentication failed","error",5e3);break;case"auth-cancelled":console.log("Authentication cancelled");break;case"auth-back":P(),E.value=!1,b.value=!0,o.showMessage("Authentication cancelled","info",3e3);break;case"auth-close-request":P();break}}async function h(){try{await Pe("/auth/api/validate",{method:"POST",credentials:"include"})}catch(c){c.status===401?(console.log("Session expired, requiring re-authentication"),_.value=!1,E.value=!0,I(),u()):console.error("Session validation error:",c)}}function p(){I(),T=setInterval(h,120*1e3)}function I(){T&&(clearInterval(T),T=null)}return Ee(async()=>{window.addEventListener("message",g),await o.loadSettings();const c=o.settings?.rp_name;if(c){const U=o.settings?.auth_host,Q=U&&N(window.location.host)!==N(U);document.title=Q?`${c} · Account summary`:c}await z()||u()}),Be(()=>{window.removeEventListener("message",g),I(),P()}),(c,$)=>(v(),w("div",ys,[ae(xt),a("main",ws,[_.value&&f.value?(v(),G(ms,{key:0,initializing:E.value},null,8,["initializing"])):_.value?(v(),G(as,{key:1})):E.value?(v(),G(St,{key:2,message:W.value},null,8,["message"])):b.value?(v(),G(Ct,{key:3,onReload:B})):V("",!0)])]))}},Qe=gt(bs);Qe.use($t());Qe.mount("#app");mt();
@@ -1 +0,0 @@
1
- .center[data-v-aea97fd3]{text-align:center}.button-row.center[data-v-aea97fd3]{display:flex;justify-content:center}.section-body[data-v-aea97fd3]{gap:1.25rem}.name-edit span[data-v-aea97fd3]{color:var(--color-text-muted);font-size:.9rem}
@@ -1 +0,0 @@
1
- import{_ as A,O as F,r as i,c as m,a4 as b,o as N,b as c,d as u,f as U,e as t,t as h,g as $,h as E,v as I,L as K,m as V,H as x,a5 as z,a6 as D,G as O,J as H,K as J}from"./_plugin-vue_export-helper-rKFEraYH.js";const L={class:"app-shell"},j={key:0,class:"global-status",style:{display:"block"}},G={class:"view-root"},Y={class:"surface surface--tight",style:{"max-width":"560px",margin:"0 auto",width:"100%"}},q={class:"view-header",style:{"text-align":"center"}},Q={class:"view-lede"},W={key:0,class:"section-block"},X={key:1,class:"section-block"},Z={key:2,class:"section-block"},ee={class:"section-body"},se={class:"name-edit"},te=["disabled"],ae=["disabled"],ne={__name:"ResetApp",setup(ie){const o=F({show:!1,message:"",type:"info"}),d=i(!0),n=i(!1),r=i(""),P=i(null),g=i(null),f=i(""),y=i("");let p=null;const R=m(()=>g.value?.session_type||"your enrollment"),T=m(()=>d.value?"Preparing your secure enrollment…":v.value?`Finish up ${R.value}. You may edit the name below if needed, and it will be saved to your passkey.`:"This authentication link is no longer valid.");m(()=>b());const v=m(()=>!!(r.value&&g.value));function l(e,s="info",a=3e3){o.show=!0,o.message=e,o.type=s,p&&clearTimeout(p),a>0&&(p=setTimeout(()=>{o.show=!1},a))}async function S(){try{const e=await V();P.value=e,e?.rp_name&&(document.title=`${e.rp_name} · Passkey Setup`)}catch(e){console.warn("Unable to load settings",e)}}async function B(){if(r.value)try{g.value=await x(`/auth/api/user-info?reset=${encodeURIComponent(r.value)}`,{method:"POST"}),f.value=g.value?.user?.user_name||""}catch(e){console.error("Failed to load user info",e);const s=e instanceof z?e.data?.detail||"The authentication link is invalid or expired.":D(e);y.value=s}}async function _(){if(!v.value||n.value)return;n.value=!0,l("Starting passkey registration…","info");let e;try{const s=f.value.trim()||null;e=await O.register(r.value,s)}catch(s){n.value=!1;const a=s?.message||"Passkey registration cancelled",k=a==="Passkey registration cancelled";l(k?a:`Registration failed: ${a}`,k?"info":"error",4e3);return}try{await C(e)}catch(s){n.value=!1;const a=s?.message||"Failed to establish session";l(a,"error",4e3);return}l("Passkey registered successfully!","success",800),setTimeout(()=>{n.value=!1,w()},800)}async function C(e){if(!e?.session_token)throw new Error("Registration response missing session_token");return await x("/auth/api/set-session",{method:"POST",headers:{Authorization:`Bearer ${e.session_token}`}})}function w(){const e=b.value||"/auth/";window.location.pathname!==e&&history.replaceState(null,"",e),window.location.reload()}function M(){const e=window.location.pathname.split("/").filter(Boolean);if(!e.length)return"";const s=e[e.length-1],a=e.slice(0,-1);return a.length>1||a.length===1&&a[0]!=="auth"||!s.includes(".")?"":s}return N(async()=>{if(r.value=M(),await S(),!r.value){const e="Reset link is missing or malformed.";y.value=e,l(e,"error",0),d.value=!1;return}await B(),d.value=!1}),(e,s)=>(u(),c("div",L,[o.show?(u(),c("div",j,[t("div",{class:$(["status",o.type])},h(o.message),3)])):U("",!0),t("main",G,[t("div",Y,[t("header",q,[s[1]||(s[1]=t("h1",null,"🔑 Registration",-1)),t("p",Q,h(T.value),1)]),d.value?(u(),c("section",W,[...s[2]||(s[2]=[t("div",{class:"section-body center"},[t("p",null,"Loading reset details…")],-1)])])):v.value?(u(),c("section",Z,[t("div",ee,[t("label",se,[s[3]||(s[3]=t("span",null,"👤 Name",-1)),E(t("input",{type:"text","onUpdate:modelValue":s[0]||(s[0]=a=>f.value=a),disabled:n.value,maxlength:"64",onKeyup:K(_,["enter"])},null,40,te),[[I,f.value]])]),t("button",{class:"btn-primary",disabled:n.value,onClick:_},h(n.value?"Registering…":"Register Passkey"),9,ae)])])):(u(),c("section",X,[t("div",{class:"section-body center"},[t("div",{class:"button-row center",style:{"justify-content":"center"}},[t("button",{class:"btn-secondary",onClick:w},"Return to sign-in")])])]))])])]))}},oe=A(ne,[["__scopeId","data-v-aea97fd3"]]);H(oe).mount("#app");J();
@@ -1,55 +0,0 @@
1
- paskia/__init__.py,sha256=6eopO87IOFA2zfOuqt8Jj8Tdtp93HBMOgUBtTzMRweM,57
2
- paskia/_version.py,sha256=3xUKhXexSTpGjDP__-RnFbAaEHHySzOSJX6zocN6QZU,704
3
- paskia/authsession.py,sha256=Do0L2b_i3zUKvRcf4p45xeCwu5ZXAwdtEPr5H8y6X7M,2305
4
- paskia/bootstrap.py,sha256=5p4kAfTeWbcM-JD6gnmKMUilhPSRIH8HyZtnVevt8Co,5764
5
- paskia/config.py,sha256=BdGzQ3Ja1enSTHmkDkBDGQk_JluT3VaK3Y7AqB5xMlk,723
6
- paskia/globals.py,sha256=YQQHDr2nCicgCSWyIKOj_vL33c7uHTCi94cKXk6y2iI,1713
7
- paskia/remoteauth.py,sha256=peu_fcINwDW8YGzLtbMq7FX7oD05bWwNLmJaMYWaKR0,12481
8
- paskia/sansio.py,sha256=O4TGgNrHAYtHR2IxRgyrB2P2Zesz7eGq-IMM1RGjvC8,9998
9
- paskia/aaguid/__init__.py,sha256=Moy67wiJSYulL_whgEEBBKabKEOvlR-NRLyXprDdBO0,1007
10
- paskia/aaguid/combined_aaguid.json,sha256=CaZ96AiwdAjBnyVZnJ1eolAHxUQMB2H6mDgZkorYg_A,4124722
11
- paskia/db/__init__.py,sha256=GzOfyLlnxsNj5i0Slhc3csasEDqsKuTgnMHNI57SMqo,4007
12
- paskia/db/background.py,sha256=Wb8pWmko0CbY48NCfBkxmmPRgPaU5U_wEA4TYNPHBe8,4005
13
- paskia/db/jsonl.py,sha256=CCl3Tlj73_Ej5NbiZQgEGrGqm6uLQF0bmmupoZ060tU,3913
14
- paskia/db/operations.py,sha256=aOrvq8YSjRuN_Ahq7nK7iTx4Uw6uBmfnmKisC-v2cwU,41591
15
- paskia/db/structs.py,sha256=ZWqAJPtixT6B5iHibss3KpDqvgzgPfP-nbSf3NGDQN4,3574
16
- paskia/fastapi/__init__.py,sha256=NFsTX1qytoyZKiur7RDTa2fxiOWHrop5CAAx8rqK9E0,58
17
- paskia/fastapi/__main__.py,sha256=174cDU95640vh0rK_dE4Wu_pi5d273qAXwmOyYIctgg,7875
18
- paskia/fastapi/admin.py,sha256=4gr09CdGScpubSajXDLxiuJUHkV4hqIINffY3wxaZhs,36871
19
- paskia/fastapi/api.py,sha256=yzI24hPKsgw-UrvEDphtB25S6NUM-9fyfz_JaQ4_PHI,10652
20
- paskia/fastapi/auth_host.py,sha256=Y5w9Mz6jyq0hj7SX8LfwebaesUOLGcWzGW9lsmw5WOo,3242
21
- paskia/fastapi/authz.py,sha256=6s2TGkb3C7qWTXHOaMj613NiqMfztqM5QENuSb2IjO8,3529
22
- paskia/fastapi/mainapp.py,sha256=nvUlKNzwHQZNhoXFVmGj9Aj2kFjklzdSNzJw8pjnimY,4442
23
- paskia/fastapi/remote.py,sha256=Qwplai_bK65WqxRA3btV_Psrl_bDF2VHN0Yzh5vwB78,19783
24
- paskia/fastapi/reset.py,sha256=8rhtqU_L17i_ZrIPPz7cXi_laWfM9_daNSnG2gS93b8,3341
25
- paskia/fastapi/session.py,sha256=9n0NuK5NtocOb27ahIU2T9eHZUog1Og_i9vvaDf7Wo8,1489
26
- paskia/fastapi/user.py,sha256=lMDzpVQ3-fprKPGu_M6vhkf9_fgR1Ak6QRqKkZhvoTE,4824
27
- paskia/fastapi/ws.py,sha256=S-KxB2KRDiF8BuhwZzJ9iDYlQjHtu3-d3ewm-TIytzk,5739
28
- paskia/fastapi/wsutil.py,sha256=CJZOyy4e9jazgyvj6CQ_kXVlGtpHNwfjGOdmHL02Nec,2620
29
- paskia/frontend-build/auth/index.html,sha256=vseFFj4Ockqhk1GkRNaHgXvEP5wpTgffhaIMuS7WANQ,936
30
- paskia/frontend-build/auth/admin/index.html,sha256=tWMDZTiWenGOTW66beypUQRxps3KYhixE2By2Wyqs8Y,862
31
- paskia/frontend-build/auth/assets/AccessDenied-Bc249ASC.css,sha256=tXoiIdVA54gVkzpqtrSidcdLB_86bB1ND-RwJSio8c0,7847
32
- paskia/frontend-build/auth/assets/AccessDenied-aTdCvz9k.js,sha256=_wCKW7fX2p8O8cfHG7PqEGLVHAVXfEvDL0tog0uY2hY,51560
33
- paskia/frontend-build/auth/assets/RestrictedAuth-BLMK7-nL.js,sha256=KAvDgEdN42Ycw3zyPONiFelfiV5xnUM9GXSnTpYfGX0,9816
34
- paskia/frontend-build/auth/assets/RestrictedAuth-DgdJyscT.css,sha256=mh35oOAdymdWc0rbTIE4oBiPzMDaNBH-ERugDl0tkSk,5397
35
- paskia/frontend-build/auth/assets/_plugin-vue_export-helper-BTzJAQlS.css,sha256=GpCu32ZoXHmL_8wVVa0Yja8dtKpaJSRyfitYAURx4Yc,12796
36
- paskia/frontend-build/auth/assets/_plugin-vue_export-helper-rKFEraYH.js,sha256=tX2rJaQDkdoiFt6YDC4vVGpMlw8cN0KuLSGdZKc5qU0,84792
37
- paskia/frontend-build/auth/assets/admin-BeNu48FR.css,sha256=jpRO6DDPrd_8gc9BhAZv_AbX8DrziF_pthO2b7DyfOw,8125
38
- paskia/frontend-build/auth/assets/admin-tVs8oyLv.js,sha256=U4vK_0OKT8Tmllk2xJc9Iv1roSaFADMLUv0A2KG0RZw,41563
39
- paskia/frontend-build/auth/assets/auth-BKX7shEe.css,sha256=331tMdRk6Ao7PNIifD8JDDjY8GD5gW9aYPM2MeLcZvg,4333
40
- paskia/frontend-build/auth/assets/auth-Dk3q4pNS.js,sha256=xFQuAuR8e35vnji0zfejipN56SDlpTlu2eyC9Ojjlms,25427
41
- paskia/frontend-build/auth/assets/forward-Dzg-aE1C.js,sha256=XZfdNI43MqAKQkui-3r7tCW_GL2GDu_NXPMzovJMcOA,782
42
- paskia/frontend-build/auth/assets/helpers-DzjFIx78.js,sha256=w_IsCBn3QwidsuwQhVRycd8Fa53lvbgRGGojTBXVlUc,940
43
- paskia/frontend-build/auth/assets/pow-2N9bxgAo.js,sha256=7AfzW5lcTefPI6YGXrYao1b56L7v5Bon9Y9N40yHsaE,9447
44
- paskia/frontend-build/auth/assets/reset-BWF4cWKR.css,sha256=8RZp0rx3cVPaxH2LjBzmyGzkrtQV6lqeAsBEG7eSetA,238
45
- paskia/frontend-build/auth/assets/reset-C_Td1_jn.js,sha256=0EtawdYcLd14KKmtwMAuvaakEjpRrZA9am-QgrZc98Q,3983
46
- paskia/frontend-build/auth/assets/restricted-C0IQufuH.js,sha256=fjCvfZTZBC7qkCKuvy-ppW3rzSD1ST9ZfE4VMR22r9w,1023
47
- paskia/frontend-build/auth/restricted/index.html,sha256=xfFuO5qpZfx8CNz9kB7fC_OjPIsoZQ1b9W5xeFE1cJ4,785
48
- paskia/frontend-build/int/forward/index.html,sha256=h4qLmAjIlGQ7ZjKV3yDsMD4SpPS2K3j4Z1BwW8DJf04,870
49
- paskia/frontend-build/int/reset/index.html,sha256=t21RLLETyTHBnKe95V053_zmfB34Vavp0fp4G5fU7-U,612
50
- paskia/migrate/__init__.py,sha256=4ZpfZbPBeJHi1Pjtq76bOi8Ev4hFDwZNXIQNuqQ3p5c,9803
51
- paskia/migrate/sql.py,sha256=qiAQooYVYdFwW-UeMwNnjLOjVAFa1tjHCZFjkkuinp0,12782
52
- paskia-0.8.1.dist-info/METADATA,sha256=gRL8oNIcCgmyIHkC5-mAiup9dwEdAgoMbzIbSqo6apE,4261
53
- paskia-0.8.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
54
- paskia-0.8.1.dist-info/entry_points.txt,sha256=vvx6RYetgd61I2ODqQPHqrKHgCfuo08w_T35yDlHenE,93
55
- paskia-0.8.1.dist-info/RECORD,,
File without changes