@aiquants/authz-react-router 0.8.1 → 0.8.3
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.
- package/dist/index.d.mts +10 -614
- package/dist/index.d.ts +10 -614
- package/dist/index.js +2 -3
- package/dist/index.mjs +2 -3
- package/package.json +8 -8
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import{data as at,redirect as dt}from"react-router";import{AUTHZ_ACTIONS as De,AuthzDeniedError as he,assertTenantId as ot,isSameTenant as We}from"@aiquants/authz-core";import{data as U,redirect as st}from"react-router";var nt={title:"Authorization (RBAC)",myPermission:"Your permissions",tabs:{roles:"Roles",resources:"Resources",role_permissions:"Permissions",user_roles:"User assignments",group_roles:"Group assignments",graph:"Graph"},common:{add:"Add",save:"Save",delete:"Delete",remove:"Remove",assign:"Assign",grant:"Grant",select:"Select\u2026",active:"\u25CB Enabled",inactive:"\xD7 Disabled",optional:"optional",tenant:"tenant",tenantHint:"must match the tenant you are signed in to",unknownTenant:"\u2014"},roles:{heading:"Roles (TMRole)",note:"Edit name / description inline and click Save (role_key is an immutable identifier).",roleKey:"role_key",name:"name",description:"description",activeHeader:"Active",empty:"No roles",newHeading:"New role",hintRoleKey:"e.g. admin"},resources:{heading:"Resources (TMResource)",note:"Edit name / description inline and click Save (app_key / resource_key are immutable identifiers).",appKey:"app_key",resourceKey:"resource_key",name:"name",description:"description",empty:"No resources",newHeading:"New resource",hintAppKey:"e.g. quants",hintResourceKey:"e.g. daily_report",hintDailyReport:"optional"},grants:{heading:"Permissions (TDRolePermission)",note:"Empty row_scope / column_scope = all rows / all columns (NULL). JSON must satisfy the row_scope / column_scope contract.",role:"role",resource:"resource",action:"action",rowScope:"row_scope",columnScope:"column_scope",empty:"No permissions",newHeading:"Grant a permission",rowScopeHint:"JSON / empty = all rows",columnScopeHint:"JSON / empty = all columns",rowScopePlaceholder:"empty = all rows (NULL)",columnScopePlaceholder:"empty = all columns (NULL)",nullRows:"NULL (all rows)",nullCols:"NULL (all columns)",selectPlaceholder:"Select\u2026"},userRoles:{heading:"User assignments (TDUserRole)",note:"Assign active roles to specific users.",user:"user",role:"role",empty:"No assignments",newHeading:"Assign a role",selectPlaceholder:"Select\u2026"},groupRoles:{heading:"Group assignments (TDGroupRole)",note:"Assign active roles to user groups.",group:"group",role:"role",empty:"No group assignments",newHeading:"Assign a role to group",selectPlaceholder:"Select\u2026"},error:{forbiddenTitle:"Access denied",forbiddenBody:"You don't have permission to view this screen. Ask an administrator to grant access.",genericTitlePrefix:"Error",genericTitle:"An error occurred",genericBody:"An unexpected error occurred. Please try again later."},warn:{selfRoleDisable:"This role backs your own authorization-admin access. Disabling it may lock you out of this screen. Continue?",selfRoleDelete:"This role backs your own authorization-admin access. Deleting it may lock you out of this screen. Continue?",selfAssignmentRemove:"This assignment backs your own authorization-admin access. Removing it may lock you out of this screen. Continue?"}};function ge(t){let n=nt;return t?{title:t.title??n.title,myPermission:t.myPermission??n.myPermission,tabs:{...n.tabs,...t.tabs},common:{...n.common,...t.common},roles:{...n.roles,...t.roles},resources:{...n.resources,...t.resources},grants:{...n.grants,...t.grants},userRoles:{...n.userRoles,...t.userRoles},groupRoles:{...n.groupRoles,...t.groupRoles},error:{...n.error,...t.error},warn:{...n.warn,...t.warn}}:n}var it=t=>t instanceof Response;function le(t){if(it(t))throw t;if(t instanceof he)throw new Response(t.message,{status:403});return U({error:t instanceof Error?t.message:"\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"},{status:400})}function Me(t){let n=t.store,d=t.resourceKey??"authz_admin",s=ge(t.labels);function c(a,l){throw new he({appKey:"",resourceKey:d,action:l,reason:"tenant-mismatch",tenantId:a.tenantId,userId:a.userId})}function p(a,l,S,f){let v=a.find(T=>T.id===l);return v||c(S,f),v}function x(a,l,S,f){let v=p(a,l,S,f);return We(S.tenantId,v.tenantId)||c(S,f),v}function o(a,l,S){We(a.tenantId,S)||c(a,l)}async function I(a,l,S){return x(await n.listRoles(a.tenantId),S,a,l)}async function K(a,l,S){return x(await n.listResources(a.tenantId),S,a,l)}async function P(a,l,S){return x(await n.listGroups(a.tenantId),S,a,l)}async function R(a,l,S){p(await n.listUsers(a.tenantId),S,a,l)}async function $(a,l,S){p(await n.listGrants(a.tenantId),S,a,l)}let A=async(a,l)=>{let{userId:S,tenantId:f,permission:v}=await t.requirePermission(a,l);if(ot(f,"createAuthzAdminServer(requirePermission.tenantId)"),S==null)throw new he({appKey:"",resourceKey:l.resourceKey,action:l.action,reason:"unresolved-user",tenantId:f,userId:null});return{userId:S,tenantId:f,permission:v}};async function G(a){await t.requireUser(a);try{let{userId:l,tenantId:S,permission:f}=await A(a,{resourceKey:d,action:"read"});return{userId:l,tenantId:S,myPermissions:{[d]:f}}}catch(l){throw l instanceof he?new Response(`Forbidden: ${d}`,{status:403}):l}}let g=async a=>{let[l,S]=await Promise.all([n.listRoles(a.tenantId),n.getSelfAdminContext(a.tenantId,Number(a.userId))]);return{roles:l,selfAdminRoleIds:S.selfAdminRoleIds,tenantId:a.tenantId,labels:s}},z=async a=>({resources:await n.listResources(a.tenantId),tenantId:a.tenantId,labels:s}),M=async a=>{let[l,S,f]=await Promise.all([n.listGrants(a.tenantId),n.listRoles(a.tenantId),n.listResources(a.tenantId)]);return{grants:l,roles:S,resources:f,tenantId:a.tenantId,labels:s}},O=async a=>{let[l,S,f,v]=await Promise.all([n.listUserRoles(a.tenantId),n.listRoles(a.tenantId),n.listUsers(a.tenantId),n.getSelfAdminContext(a.tenantId,Number(a.userId))]);return{assignments:l,roles:S,users:f,actorUserId:v.actorUserId,selfAdminRoleIds:v.selfAdminRoleIds,tenantId:a.tenantId,labels:s}},re=async a=>{let[l,S,f]=await Promise.all([n.listGroupRoles(a.tenantId),n.listRoles(a.tenantId),n.listGroups(a.tenantId)]);return{groupRoles:l,roles:S,groups:f,tenantId:a.tenantId,labels:s}},ae=async a=>{let[l,S,f,v,T,L,E]=await Promise.all([n.listUsers(a.tenantId),n.listRoles(a.tenantId),n.listResources(a.tenantId),n.listGrants(a.tenantId),n.listUserRoles(a.tenantId),n.listGroupRoles(a.tenantId),n.listGroups(a.tenantId)]);return{users:l,roles:S,resources:f,grants:v,assignments:T,groupRoles:L,groups:E,tenantId:a.tenantId,labels:s}};return{labels:s,resourceKey:d,layoutGuard:G,layout:{async loader({request:a}){let{tenantId:l,myPermissions:S}=await G(a);return{myPermissions:S,tenantId:l,labels:s,adminResourceKey:d}}},index:{loader(){throw st("/authz/roles")}},roles:{data:g,async loader({request:a}){let l=await A(a,{resourceKey:d,action:"read"});return g(l)},async action({request:a}){let l=await a.formData(),S=String(l.get("_action"));try{switch(S){case"create":{let f=await A(a,{resourceKey:d,action:"create"}),v=String(l.get("tenantId")??"").trim(),T=String(l.get("roleKey")??"").trim(),L=String(l.get("name")??"").trim();return v&&T&&L?(o(f,"create",v),await n.createRole(f.tenantId,{tenantId:v,roleKey:T,name:L,description:String(l.get("description")??"").trim()||null},String(f.userId)),{ok:!0}):U({error:"tenant_id \u3068 role_key \u3068 name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"save":{let f=await A(a,{resourceKey:d,action:"update"}),v=String(l.get("tenantId")??"").trim(),T=String(l.get("roleKey")??"").trim(),L=String(l.get("name")??"").trim();if(!(v&&T&&L))return U({error:"tenantId \u3068 roleKey \u3068 name \u306F\u5FC5\u9808\u3067\u3059"},{status:400});o(f,"update",v);let E=await I(f,"update",Number(l.get("id")));return await n.updateRole(f.tenantId,E.id,{tenantId:v,roleKey:T,name:L,description:String(l.get("description")??"").trim()||null},String(f.userId)),{ok:!0}}case"toggle":{let f=await A(a,{resourceKey:d,action:"update"}),v=await I(f,"update",Number(l.get("id")));return await n.setRoleActive(f.tenantId,v.id,l.get("isActive")==="true",String(f.userId)),{ok:!0}}case"delete":{let f=await A(a,{resourceKey:d,action:"delete"}),v=await I(f,"delete",Number(l.get("id")));return await n.deleteRole(f.tenantId,v.id),{ok:!0}}default:return U({error:"unknown action"},{status:400})}}catch(f){return le(f)}}},resources:{data:z,async loader({request:a}){let l=await A(a,{resourceKey:d,action:"read"});return z(l)},async action({request:a}){let l=await a.formData(),S=String(l.get("_action"));try{switch(S){case"create":{let f=await A(a,{resourceKey:d,action:"create"}),v=String(l.get("tenantId")??"").trim(),T=String(l.get("appKey")??"").trim(),L=String(l.get("resourceKey")??"").trim(),E=String(l.get("name")??"").trim();return v&&T&&L&&E?(o(f,"create",v),await n.createResource(f.tenantId,{tenantId:v,appKey:T,resourceKey:L,name:E,description:String(l.get("description")??"").trim()||null},String(f.userId)),{ok:!0}):U({error:"tenant_id / app_key / resource_key / name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"save":{let f=await A(a,{resourceKey:d,action:"update"}),v=String(l.get("name")??"").trim();if(!v)return U({error:"name \u306F\u5FC5\u9808\u3067\u3059"},{status:400});let T=await K(f,"update",Number(l.get("id")));return await n.updateResource(f.tenantId,T.id,{name:v,description:String(l.get("description")??"").trim()||null},String(f.userId)),{ok:!0}}case"delete":{let f=await A(a,{resourceKey:d,action:"delete"}),v=await K(f,"delete",Number(l.get("id")));return await n.deleteResource(f.tenantId,v.id),{ok:!0}}default:return U({error:"unknown action"},{status:400})}}catch(f){return le(f)}}},grants:{data:M,async loader({request:a}){let l=await A(a,{resourceKey:d,action:"read"});return M(l)},async action({request:a}){let l=await a.formData(),S=String(l.get("_action"));try{switch(S){case"create":{let f=await A(a,{resourceKey:d,action:"create"}),v=String(l.get("tenantId")??"").trim(),T=Number(l.get("roleId")),L=Number(l.get("resourceId"));if(!(v&&T&&L))return U({error:"tenant_id \u3068\u30ED\u30FC\u30EB\u3068\u30EA\u30BD\u30FC\u30B9\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044"},{status:400});let E=String(l.get("action")??"");if(!De.includes(E))return U({error:"\u7121\u52B9\u306A action \u3067\u3059"},{status:400});let Z=E;o(f,"create",v);let Q=await I(f,"create",T),y=await K(f,"create",L);return await n.createGrant(f.tenantId,{tenantId:v,roleId:Q.id,resourceId:y.id,action:Z,rowScope:String(l.get("rowScope")??""),columnScope:String(l.get("columnScope")??"")},String(f.userId)),{ok:!0}}case"save":{let f=await A(a,{resourceKey:d,action:"update"}),v=String(l.get("action")??"");if(!De.includes(v))return U({error:"\u7121\u52B9\u306A action \u3067\u3059"},{status:400});let T=v,L=Number(l.get("id"));return await $(f,"update",L),await n.updateGrant(f.tenantId,L,{action:T,rowScope:String(l.get("rowScope")??""),columnScope:String(l.get("columnScope")??"")},String(f.userId)),{ok:!0}}case"delete":{let f=await A(a,{resourceKey:d,action:"delete"}),v=Number(l.get("id"));return await $(f,"delete",v),await n.deleteGrant(f.tenantId,v),{ok:!0}}default:return U({error:"unknown action"},{status:400})}}catch(f){return le(f)}}},userRoles:{data:O,async loader({request:a}){let l=await A(a,{resourceKey:d,action:"read"});return O(l)},async action({request:a}){let l=await a.formData(),S=String(l.get("_action"));try{switch(S){case"assign":{let f=await A(a,{resourceKey:d,action:"create"}),v=Number(l.get("userId")),T=Number(l.get("roleId"));if(!(v&&T))return U({error:"\u30E6\u30FC\u30B6\u30FC\u3068\u30ED\u30FC\u30EB\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044"},{status:400});await R(f,"create",v);let L=await I(f,"create",T);return await n.assignUserRole(f.tenantId,v,L.id,String(f.userId)),{ok:!0}}case"remove":{let f=await A(a,{resourceKey:d,action:"delete"}),v=Number(l.get("userId"));await R(f,"delete",v);let T=await I(f,"delete",Number(l.get("roleId")));return await n.removeUserRole(f.tenantId,v,T.id),{ok:!0}}default:return U({error:"unknown action"},{status:400})}}catch(f){return le(f)}}},groupRoles:{data:re,async loader({request:a}){let l=await A(a,{resourceKey:d,action:"read"});return re(l)},async action({request:a}){let l=await a.formData(),S=String(l.get("_action"));try{switch(S){case"assign":{let f=await A(a,{resourceKey:d,action:"create"}),v=Number(l.get("groupId")),T=Number(l.get("roleId"));if(!(v&&T))return U({error:"\u30B0\u30EB\u30FC\u30D7\u3068\u30ED\u30FC\u30EB\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044"},{status:400});let L=await P(f,"create",v),E=await I(f,"create",T);return await n.assignGroupRole(f.tenantId,L.id,E.id,String(f.userId)),{ok:!0}}case"remove":{let f=await A(a,{resourceKey:d,action:"delete"}),v=await P(f,"delete",Number(l.get("groupId"))),T=await I(f,"delete",Number(l.get("roleId")));return await n.removeGroupRole(f.tenantId,v.id,T.id),{ok:!0}}default:return U({error:"unknown action"},{status:400})}}catch(f){return le(f)}}},graph:{data:ae,async loader({request:a}){let l=await A(a,{resourceKey:d,action:"read"});return ae(l)}}}}function Ne(t){return String(t["*"]??"").split("/")[0]}function qt(t){let n=Me(t),d=t.basePath??"/authz",s=["roles","resources","role_permissions","user_roles","group_roles","graph"],c={roles:n.roles.data,resources:n.resources.data,role_permissions:n.grants.data,user_roles:n.userRoles.data,group_roles:n.groupRoles.data,graph:n.graph.data},p=new Map([["roles",n.roles.action],["resources",n.resources.action],["role_permissions",n.grants.action],["user_roles",n.userRoles.action],["group_roles",n.groupRoles.action]]);async function x(I){let K=Ne(I.params);if(!s.includes(K))throw dt(`${d}/roles`);let{userId:P,tenantId:R,myPermissions:$}=await n.layoutGuard(I.request),A=await c[K]({tenantId:R,userId:P});return{segment:K,basePath:d,myPermissions:$,adminResourceKey:n.resourceKey,...A}}async function o(I){let K=Ne(I.params),P=p.get(K);return P?P(I):at({error:"unknown action"},{status:400})}return{loader:x,action:o,server:n}}import{jsx as lt,jsxs as Ie}from"react/jsx-runtime";var i={page:{padding:"1.25rem",maxWidth:1280,margin:"0 auto",color:"#0f172a"},tableContainer:{width:"100%",overflowX:"auto",marginBottom:"1rem",WebkitOverflowScrolling:"touch"},table:{borderCollapse:"collapse",width:"100%",fontSize:"0.9rem",tableLayout:"fixed"},th:{textAlign:"left",borderBottom:"2px solid #e2e8f0",padding:"0.45rem 0.65rem",fontSize:"0.78rem",color:"#475569",fontWeight:600,textTransform:"uppercase",letterSpacing:"0.03em"},td:{borderBottom:"1px solid #f1f5f9",padding:"0.5rem 0.65rem",verticalAlign:"middle",wordBreak:"break-all"},input:{padding:"0.4rem 0.55rem",border:"1px solid #cbd5e1",borderRadius:6,fontSize:"0.9rem",background:"#fff",width:"100%",boxSizing:"border-box"},select:{padding:"0.4rem 0.55rem",border:"1px solid #cbd5e1",borderRadius:6,fontSize:"0.9rem",background:"#fff",width:"100%",boxSizing:"border-box"},textarea:{padding:"0.4rem 0.55rem",border:"1px solid #cbd5e1",borderRadius:6,fontSize:"0.82rem",fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",minHeight:"3.25rem",resize:"vertical",width:"100%",boxSizing:"border-box"},button:{padding:"0.3rem 0.7rem",border:"1px solid #cbd5e1",borderRadius:6,background:"#fff",cursor:"pointer",fontSize:"0.82rem",color:"#334155"},save:{padding:"0.3rem 0.7rem",border:"1px solid #2563eb",borderRadius:6,background:"#eff6ff",cursor:"pointer",fontSize:"0.82rem",color:"#2563eb",fontWeight:600},danger:{padding:"0.3rem 0.7rem",border:"1px solid #fecaca",borderRadius:6,background:"#fff",cursor:"pointer",fontSize:"0.82rem",color:"#dc2626"},primary:{padding:"0.5rem 1.25rem",border:"1px solid #2563eb",borderRadius:6,background:"#2563eb",color:"#fff",cursor:"pointer",fontSize:"0.9rem",fontWeight:600,alignSelf:"flex-start"},card:{display:"flex",flexDirection:"column",gap:"0.85rem",maxWidth:600,marginTop:"0.75rem",padding:"1rem 1.1rem",border:"1px solid #e2e8f0",borderRadius:10,background:"#f8fafc"},code:{fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",fontSize:"0.78rem",color:"#334155",wordBreak:"break-all"},muted:{color:"#94a3b8"},h2:{fontSize:"1.05rem",margin:"0 0 0.35rem",fontWeight:700},h3:{fontSize:"0.92rem",margin:"1.25rem 0 0",color:"#334155",fontWeight:600},note:{color:"#64748b",fontSize:"0.82rem",margin:"0 0 0.75rem"},empty:{color:"#94a3b8",padding:"0.75rem 0.65rem"}};function N({label:t,hint:n,children:d}){return Ie("div",{style:{display:"flex",flexDirection:"column",gap:"0.3rem"},children:[Ie("span",{style:{fontSize:"0.8rem",color:"#475569",fontWeight:600},children:[t,n?Ie("span",{style:{fontWeight:400,color:"#94a3b8"},children:[" \u2014 ",n]}):null]}),d]})}function de({message:t}){return t?lt("p",{role:"alert",style:{color:"#dc2626",background:"#fef2f2",border:"1px solid #fecaca",borderRadius:8,padding:"0.55rem 0.8rem",fontSize:"0.85rem",margin:"0.25rem 0"},children:t}):null}import{AUTHZ_ACTIONS as Fe}from"@aiquants/authz-core";import{SelectBox as ne}from"@aiquants/select-box";import{useState as V}from"react";import{Form as B,isRouteErrorResponse as ht,NavLink as bt,Outlet as xt,useActionData as ce,useLoaderData as oe,useRouteError as vt}from"react-router";import{useEffect as pt,useRef as mt,useState as ft}from"react";function Ee(t){let n=t?.canRead?t.readPartial?"partial":"full":"none",d=t?.canCreate&&t?.canUpdate?"full":t?.canCreate||t?.canUpdate?"partial":"none",s=t?.canDelete?"full":"none";return{canRead:!!t?.canRead,canCreate:!!t?.canCreate,canUpdate:!!t?.canUpdate,canDelete:!!t?.canDelete,canWrite:!!t?.canWrite,readState:n,writeState:d,deleteState:s}}import{jsx as J,jsxs as ue}from"react/jsx-runtime";var ut={full:{bg:"#ecfdf5",text:"#047857",border:"#a7f3d0"},partial:{bg:"#fffbeb",text:"#b45309",border:"#fde68a"},none:{bg:"#f8fafc",text:"#94a3b8",border:"#cbd5e1"}};function _e(t,n){let d=t?.trim(),s=n?.trim();if(s&&d&&s!==d)return`\u5BFE\u8C61\u30EA\u30BD\u30FC\u30B9: ${s} (${d})`;if(s||d)return`\u5BFE\u8C61\u30EA\u30BD\u30FC\u30B9: ${s||d}`}function ct({state:t}){return t==="full"?J("svg",{style:{width:"0.85rem",height:"0.85rem",flexShrink:0},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:3,"aria-hidden":"true",children:J("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 13l4 4L19 7"})}):t==="partial"?J("svg",{style:{width:"0.85rem",height:"0.85rem",flexShrink:0},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2.5,"aria-hidden":"true",children:J("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}):J("svg",{style:{width:"0.85rem",height:"0.85rem",flexShrink:0},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2.5,"aria-hidden":"true",children:J("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"})})}function Ae({permission:t,resourceName:n,expectedResourceKey:d,showResourceTooltip:s=!0,labels:c,showScopeSummary:p=!0,className:x="authz-permission-indicator"}){let o=Ee(t),I={read:c?.read??"\u95B2\u89A7",write:c?.write??"\u7DE8\u96C6",delete:c?.delete??"\u524A\u9664"},K=t?.resourceKey,P=n||K,R=s?_e(K,n):void 0,$=!!(d&&K&&K!==d);$&&typeof console<"u"&&typeof console.error=="function"&&console.error(`[Authz Warning] Resource key mismatch in MyPermissionIndicator! Expected: "${d}", but received permission for: "${K}".`);let A=(G,g,z)=>{let M=ut[g],O=R?`${z}: ${g}
|
|
2
|
-
${R}`:`${z}: ${g}`;return ue("span",{"data-perm":G,"data-state":g,title:O,style:{display:"inline-flex",alignItems:"center",gap:"0.25rem",padding:"0.2rem 0.5rem",borderRadius:"100px",fontSize:"0.75rem",fontWeight:600,backgroundColor:M.bg,color:M.text,border:`1px solid ${M.border}`,lineHeight:1,userSelect:"none"},children:[J(ct,{state:g}),J("span",{children:z})]})};return ue("span",{className:x,title:R,"data-resource":K??"","data-resource-name":P??"","data-mismatch":$?"true":void 0,style:{display:"inline-flex",gap:"0.35rem",alignItems:"center",verticalAlign:"middle"},children:[A("read",o.readState,I.read),A("write",o.writeState,I.write),A("delete",o.deleteState,I.delete),p&&o.readState==="partial"?J("span",{"data-perm":"scope",title:R,style:{fontSize:"0.7rem",color:"#b45309",backgroundColor:"#fef3c7",padding:"0.15rem 0.35rem",borderRadius:"4px",fontWeight:600},children:"\u90E8\u5206\u5236\u9650"}):null,$?ue("span",{"data-testid":"resource-mismatch-warning",title:`expected: "${d}", actual: "${K}"`,style:{fontSize:"0.7rem",color:"#991b1b",backgroundColor:"#fee2e2",border:"1px solid #fca5a5",padding:"0.15rem 0.35rem",borderRadius:"4px",fontWeight:700},children:["\u26A0\uFE0F \u30EA\u30BD\u30FC\u30B9\u4E0D\u4E00\u81F4 (",K," \u2260 ",d,")"]}):null]})}function Xt({permission:t,resourceName:n,expectedResourceKey:d,prefixLabel:s="\u3042\u306A\u305F\u306E\u6A29\u9650",showPrefixLabel:c=!0,showResourceTooltip:p=!0,labels:x,showScopeSummary:o=!0,className:I="authz-permission-status",style:K}){let P=t?.resourceKey,R=n||P,$=p?_e(P,n):void 0;return ue("span",{className:I,title:$,"data-testid":"my-permission-status","data-resource":P??"","data-resource-name":R??"",style:{fontSize:"0.82rem",color:"#475569",display:"inline-flex",alignItems:"center",gap:"0.4rem",...K},children:[c&&ue("span",{"data-testid":"prefix-label",children:[s,":"]}),J(Ae,{permission:t,resourceName:n,expectedResourceKey:d,showResourceTooltip:p,labels:x,showScopeSummary:o})]})}import{jsx as te,jsxs as H}from"react/jsx-runtime";function Re(t,n=0){let d=[];for(let s of t){let c=s.level??n;d.push({...s,level:c}),s.children&&s.children.length>0&&d.push(...Re(s.children,c+1))}return d}var Oe={"2xs":{fontSize:"0.6rem",pillPadding:"0.05rem 0.25rem",pillGap:"0.15rem",wrapperGap:"0.15rem",triggerPadding:"0.1rem 0.35rem",triggerFontSize:"0.62rem",badgeFontSize:"0.58rem"},xs:{fontSize:"0.65rem",pillPadding:"0.08rem 0.35rem",pillGap:"0.18rem",wrapperGap:"0.2rem",triggerPadding:"0.12rem 0.4rem",triggerFontSize:"0.68rem",badgeFontSize:"0.62rem"},sm:{fontSize:"0.72rem",pillPadding:"0.1rem 0.4rem",pillGap:"0.2rem",wrapperGap:"0.25rem",triggerPadding:"0.15rem 0.45rem",triggerFontSize:"0.72rem",badgeFontSize:"0.65rem"},md:{fontSize:"0.78rem",pillPadding:"0.15rem 0.5rem",pillGap:"0.3rem",wrapperGap:"0.35rem",triggerPadding:"0.2rem 0.6rem",triggerFontSize:"0.78rem",badgeFontSize:"0.7rem"},lg:{fontSize:"0.85rem",pillPadding:"0.25rem 0.65rem",pillGap:"0.4rem",wrapperGap:"0.45rem",triggerPadding:"0.25rem 0.75rem",triggerFontSize:"0.85rem",badgeFontSize:"0.75rem"}};function yt(t,n){let d=n?.noPermission??"\u6A29\u9650\u306A\u3057",s=n?.fullWrite??"\u7DE8\u96C6\u53EF",c=n?.partialRead??"\u4E00\u90E8\u95B2\u89A7",p=n?.readOnly??"\u95B2\u89A7\u306E\u307F";return t&&(t.canRead||t.canWrite||t.canDelete)?t.canWrite?{text:s,color:"#047857",bgColor:"#ecfdf5",borderColor:"#a7f3d0"}:t.canRead?t.readPartial?{text:c,color:"#b45309",bgColor:"#fffbeb",borderColor:"#fde68a"}:{text:p,color:"#1d4ed8",bgColor:"#eff6ff",borderColor:"#bfdbfe"}:{text:d,color:"#64748b",bgColor:"#f1f5f9",borderColor:"#cbd5e1"}:{text:d,color:"#64748b",bgColor:"#f1f5f9",borderColor:"#cbd5e1"}}function gt({item:t,size:n="md",labels:d}){let s=yt(t.permission,d),c=t.permission?.resourceKey||t.resourceKey||t.expectedResourceKey,p=t.resourceName||c,x=!!(t.expectedResourceKey&&t.permission?.resourceKey&&t.permission.resourceKey!==t.expectedResourceKey),o=Oe[n],I=`\u5BFE\u8C61: ${p}${c?` (${c})`:""}${t.permission?` | ${d?.read??"\u95B2\u89A7"}:${t.permission.canRead?"\u25CB":"\xD7"} ${d?.write??"\u7DE8\u96C6"}:${t.permission.canWrite?"\u25CB":"\xD7"} ${d?.delete??"\u524A\u9664"}:${t.permission.canDelete?"\u25CB":"\xD7"}`:""}`;return H("span",{title:I,"data-testid":`permission-pill-${t.resourceName}`,"data-mismatch":x?"true":"false",style:{display:"inline-flex",alignItems:"center",gap:o.pillGap,fontSize:o.fontSize,padding:o.pillPadding,borderRadius:"9999px",backgroundColor:x?"#fee2e2":s.bgColor,color:x?"#991b1b":s.color,border:`1px solid ${x?"#fca5a5":s.borderColor}`,fontWeight:600,lineHeight:"1.2"},children:[H("span",{children:[p,":"]}),te("span",{children:s.text}),x&&te("span",{title:`expected "${t.expectedResourceKey}", actual "${t.permission?.resourceKey}"`,children:"\u26A0\uFE0F"})]})}function Ue({items:t,prefixLabel:n="\u3042\u306A\u305F\u306E\u6A29\u9650",variant:d="pills",size:s="md",labels:c,className:p="authz-permission-group-status",style:x}){let[o,I]=ft(!1),K=mt(null),P=Oe[s];if(pt(()=>{if(d!=="popover"||!o)return;function R(A){K.current&&!K.current.contains(A.target)&&I(!1)}function $(A){A.key==="Escape"&&I(!1)}return document.addEventListener("mousedown",R),document.addEventListener("keydown",$),()=>{document.removeEventListener("mousedown",R),document.removeEventListener("keydown",$)}},[d,o]),d==="popover"){let R=Re(t),$=R.filter(z=>z.permission?.canWrite).length,A=R.filter(z=>z.permission?.canRead).length,G=R.length,g=G===0||$===0&&A===0?c?.noPermission??"\u6A29\u9650\u306A\u3057":$===G?c?.fullWrite??"\u7DE8\u96C6\u53EF":$>0?c?.partialWrite??"\u4E00\u90E8\u7DE8\u96C6\u53EF":c?.readOnly??"\u95B2\u89A7\u306E\u307F";return H("span",{ref:K,className:p,"data-testid":"my-permission-group-popover",style:{position:"relative",display:"inline-block",...x},children:[H("button",{type:"button",onClick:()=>I(!o),"data-testid":"permission-popover-trigger",style:{display:"inline-flex",alignItems:"center",gap:P.wrapperGap,fontSize:P.triggerFontSize,padding:P.triggerPadding,borderRadius:"6px",backgroundColor:"#f8fafc",color:"#334155",border:"1px solid #cbd5e1",fontWeight:600,cursor:"pointer"},children:[H("span",{children:["\u{1F512} ",n]}),H("span",{style:{fontSize:P.badgeFontSize,color:"#64748b"},children:["(",g,")"]}),te("span",{style:{fontSize:"0.65rem",marginLeft:"0.1rem"},children:o?"\u25B2":"\u25BE"})]}),o&&H("div",{"data-testid":"permission-popover-card",style:{position:"absolute",top:"calc(100% + 6px)",right:0,zIndex:50,minWidth:"280px",whiteSpace:"nowrap",padding:"0.75rem 0.85rem",backgroundColor:"#ffffff",borderRadius:"8px",boxShadow:"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",border:"1px solid #e2e8f0",fontSize:"0.82rem"},children:[H("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"0.5rem",paddingBottom:"0.4rem",borderBottom:"1px solid #f1f5f9",fontWeight:700,color:"#1e293b",whiteSpace:"nowrap"},children:[H("span",{children:["\u{1F512} ",n]}),te("button",{type:"button",onClick:()=>I(!1),style:{border:"none",background:"none",cursor:"pointer",color:"#94a3b8",fontSize:"0.85rem",padding:"0 0.2rem"},children:"\u2715"})]}),te("div",{style:{display:"flex",flexDirection:"column",gap:"0.4rem"},children:Re(t).map(z=>{let M=z.level??0,O=M>0;return H("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:"1.25rem",whiteSpace:"nowrap",paddingLeft:O?`${M*.85}rem`:"0"},children:[H("div",{style:{display:"inline-flex",alignItems:"center",whiteSpace:"nowrap"},children:[O&&te("span",{"aria-hidden":"true",style:{display:"inline-block",width:"10px",height:"10px",borderLeft:"1.5px solid #cbd5e1",borderBottom:"1.5px solid #cbd5e1",borderBottomLeftRadius:"3px",marginRight:"6px",marginTop:"-4px",flexShrink:0}}),H("span",{style:{fontWeight:O?500:600,color:O?"#64748b":"#1e293b",fontSize:O?"0.78rem":"0.82rem",whiteSpace:"nowrap"},children:[z.resourceName,":"]})]}),te(Ae,{permission:z.permission,resourceName:z.resourceName,expectedResourceKey:z.expectedResourceKey,labels:c})]},z.resourceName)})})]})]})}return H("span",{className:p,"data-testid":"my-permission-group-pills",style:{display:"inline-flex",alignItems:"center",flexWrap:"wrap",gap:P.pillGap,fontSize:P.fontSize,color:"#475569",...x},children:[n&&H("span",{style:{fontWeight:600,color:"#334155"},children:[n,":"]}),te("span",{style:{display:"inline-flex",alignItems:"center",flexWrap:"wrap",gap:P.pillGap},children:t.map(R=>te(gt,{item:R,size:s,labels:c},R.resourceName))})]})}import{Fragment as Pe,jsx as e,jsxs as u}from"react/jsx-runtime";var pe=t=>t?.error;function me({tenantId:t,testId:n}){return e("td",{style:i.td,children:e("span",{style:i.code,"data-testid":n,children:t})})}function ke(t,n,d){let s=t.find(c=>c.id===n);return s?s.tenantId:d.common.unknownTenant}function qe({children:t,renderHeader:n}){let{myPermissions:d,labels:s,adminResourceKey:c,basePath:p,tenantId:x}=oe(),o=p??"/authz",[I,K]=V("pills"),P=[["roles",s.tabs.roles],["resources",s.tabs.resources],["role_permissions",s.tabs.role_permissions],["user_roles",s.tabs.user_roles],["group_roles",s.tabs.group_roles],["graph",s.tabs.graph]],R=Object.entries(d||{}).map(([G,g])=>({resourceKey:G,resourceName:g?.resourceKey||G,permission:g,expectedResourceKey:G})),$=R.length>0?R:[{resourceKey:c,resourceName:c,permission:d?.[c],expectedResourceKey:c}],A=u("div",{style:{display:"flex",alignItems:"center",gap:"0.4rem"},children:[u("span",{"data-testid":"authz-tenant-badge",style:{...i.code,border:"1px solid #cbd5e1",borderRadius:4,padding:"1px 6px",background:"#f8fafc"},children:[s.common.tenant,": ",x]}),e(Ue,{prefixLabel:s.myPermission,items:$,variant:I,size:"xs"}),u("div",{style:{display:"inline-flex",borderRadius:"4px",border:"1px solid #cbd5e1",padding:"1px",backgroundColor:"#f8fafc",fontSize:"0.7rem"},children:[e("button",{type:"button",onClick:()=>K("pills"),"data-testid":"switch-variant-pills",style:{padding:"1px 5px",borderRadius:"3px",border:"none",cursor:"pointer",fontSize:"0.7rem",lineHeight:"1.2",fontWeight:I==="pills"?600:400,backgroundColor:I==="pills"?"#ffffff":"transparent",color:I==="pills"?"#1e293b":"#64748b",boxShadow:I==="pills"?"0 1px 2px rgba(0,0,0,0.05)":"none"},children:"Pills"}),e("button",{type:"button",onClick:()=>K("popover"),"data-testid":"switch-variant-popover",style:{padding:"1px 5px",borderRadius:"3px",border:"none",cursor:"pointer",fontSize:"0.7rem",lineHeight:"1.2",fontWeight:I==="popover"?600:400,backgroundColor:I==="popover"?"#ffffff":"transparent",color:I==="popover"?"#1e293b":"#64748b",boxShadow:I==="popover"?"0 1px 2px rgba(0,0,0,0.05)":"none"},children:"Popover"})]})]});return u("div",{className:"authz-admin",style:i.page,children:[n?n({title:s.title,annotation:A}):u("header",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:"0.75rem",flexWrap:"wrap",margin:"0 0 0.4rem"},children:[e("h1",{style:{fontSize:"1.15rem",margin:0,fontWeight:700,color:"#1e293b"},children:s.title}),A]}),e("nav",{style:{display:"flex",gap:"0.25rem",borderBottom:"1px solid #e2e8f0",margin:"0.6rem 0 1rem"},children:P.map(([G,g])=>e(bt,{to:`${o}/${G}`,style:({isActive:z})=>({padding:"0.5rem 0.9rem",textDecoration:"none",color:z?"#2563eb":"#475569",borderBottom:z?"2px solid #2563eb":"2px solid transparent",marginBottom:-1,fontWeight:z?700:500,fontSize:"0.92rem"}),children:g},G))}),t]})}function ur({renderHeader:t}={}){return e(qe,{renderHeader:t,children:e(xt,{})})}function wt(t){let n=ge(t).error;return function(){let s=vt(),c=ht(s)?s:null,p=c?.status===403||typeof s=="object"&&s!==null&&s.status===403,x=p?n.forbiddenTitle:c?`${n.genericTitlePrefix} (${c.status})`:n.genericTitle,o=p?n.forbiddenBody:c?typeof c.data=="string"&&c.data?c.data:c.statusText:n.genericBody;return e("div",{style:i.page,children:u("div",{role:"alert",style:{maxWidth:480,margin:"3rem auto",padding:"1.5rem",border:"1px solid #fecaca",borderRadius:12,background:"#fef2f2"},children:[e("h1",{style:{fontSize:"1.1rem",fontWeight:700,color:"#b91c1c",margin:"0 0 0.5rem"},children:x}),e("p",{style:{color:"#7f1d1d",fontSize:"0.9rem",margin:0,lineHeight:1.7},children:o})]})})}}var cr=wt(),Se=(t,n)=>d=>{t&&!window.confirm(n)&&d.preventDefault()};function He(){let{roles:t,selfAdminRoleIds:n,labels:d,tenantId:s}=oe(),c=d.roles,p=d.common,x=new Set(n??[]);return u("section",{children:[e("h2",{style:i.h2,children:c.heading}),e(de,{message:pe(ce())}),e("p",{style:i.note,children:c.note}),e("div",{style:i.tableContainer,children:u("table",{style:i.table,children:[e("thead",{children:u("tr",{children:[e("th",{style:{...i.th,width:"12%"},children:p.tenant}),e("th",{style:{...i.th,width:"18%"},children:c.roleKey}),e("th",{style:{...i.th,width:"22%"},children:c.name}),e("th",{style:{...i.th,width:"28%"},children:c.description}),e("th",{style:{...i.th,width:"10%"},children:c.activeHeader}),e("th",{style:{...i.th,width:"10%"}})]})}),u("tbody",{children:[t.map(o=>u("tr",{children:[e(me,{tenantId:o.tenantId,testId:`tenant-role-${o.id}`}),u("td",{style:i.td,children:[e("input",{type:"hidden",name:"tenantId",value:o.tenantId,form:`save-role-${o.id}`}),o.roleKey==="@authenticated"||o.roleKey==="@anonymous"?e("span",{style:i.code,children:o.roleKey}):e("input",{name:"roleKey",defaultValue:o.roleKey,form:`save-role-${o.id}`,"aria-label":`roleKey-${o.id}`,required:!0,style:i.input})]}),e("td",{style:i.td,children:e("input",{name:"name",defaultValue:o.name,form:`save-role-${o.id}`,"aria-label":`name-${o.id}`,required:!0,style:i.input})}),e("td",{style:i.td,children:e("input",{name:"description",defaultValue:o.description??"",form:`save-role-${o.id}`,"aria-label":`description-${o.id}`,style:i.input})}),e("td",{style:i.td,children:u(B,{method:"post",style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"toggle"}),e("input",{type:"hidden",name:"id",value:o.id}),e("input",{type:"hidden",name:"isActive",value:String(!o.isActive)}),e("button",{type:"submit",style:i.button,onClick:o.isActive?Se(x.has(o.id),d.warn.selfRoleDisable):void 0,children:o.isActive?p.active:p.inactive})]})}),u("td",{style:{...i.td,whiteSpace:"nowrap"},children:[u(B,{method:"post",id:`save-role-${o.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:o.id}),e("button",{type:"submit",style:i.save,children:p.save})]}),u(B,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:o.id}),e("button",{type:"submit",style:i.danger,onClick:Se(x.has(o.id),d.warn.selfRoleDelete),children:p.delete})]})]})]},o.id)),t.length===0?e("tr",{children:e("td",{style:i.empty,colSpan:6,children:c.empty})}):null]})]})}),e("h3",{style:i.h3,children:c.newHeading}),u(B,{method:"post",style:i.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e(N,{label:p.tenant,hint:p.tenantHint,children:e("input",{name:"tenantId","aria-label":"tenant_id",defaultValue:s,required:!0,style:i.input})}),e(N,{label:c.roleKey,hint:c.hintRoleKey,children:e("input",{name:"roleKey","aria-label":"role_key",required:!0,style:i.input})}),e(N,{label:c.name,children:e("input",{name:"name","aria-label":"name",required:!0,style:i.input})}),e(N,{label:c.description,hint:p.optional,children:e("input",{name:"description","aria-label":"description",style:i.input})}),e("button",{type:"submit",style:i.primary,children:p.add})]})]})}function It(){let{resources:t,labels:n,tenantId:d}=oe(),s=n.resources,c=n.common;return u("section",{children:[e("h2",{style:i.h2,children:s.heading}),e(de,{message:pe(ce())}),e("p",{style:i.note,children:s.note}),e("div",{style:i.tableContainer,children:u("table",{style:i.table,children:[e("thead",{children:u("tr",{children:[e("th",{style:{...i.th,width:"12%"},children:c.tenant}),e("th",{style:{...i.th,width:"13%"},children:s.appKey}),e("th",{style:{...i.th,width:"18%"},children:s.resourceKey}),e("th",{style:{...i.th,width:"22%"},children:s.name}),e("th",{style:{...i.th,width:"25%"},children:s.description}),e("th",{style:{...i.th,width:"10%"}})]})}),u("tbody",{children:[t.map(p=>u("tr",{children:[e(me,{tenantId:p.tenantId,testId:`tenant-resource-${p.id}`}),e("td",{style:i.td,children:e("span",{style:i.code,children:p.appKey})}),e("td",{style:i.td,children:e("span",{style:i.code,children:p.resourceKey})}),e("td",{style:i.td,children:e("input",{name:"name",defaultValue:p.name,form:`save-res-${p.id}`,"aria-label":`name-${p.id}`,required:!0,style:i.input})}),e("td",{style:i.td,children:e("input",{name:"description",defaultValue:p.description??"",form:`save-res-${p.id}`,"aria-label":`description-${p.id}`,style:i.input})}),u("td",{style:{...i.td,whiteSpace:"nowrap"},children:[u(B,{method:"post",id:`save-res-${p.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:p.id}),e("button",{type:"submit",style:i.save,children:c.save})]}),u(B,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:p.id}),e("button",{type:"submit",style:i.danger,children:c.delete})]})]})]},p.id)),t.length===0?e("tr",{children:e("td",{style:i.empty,colSpan:6,children:s.empty})}):null]})]})}),e("h3",{style:i.h3,children:s.newHeading}),u(B,{method:"post",style:i.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e(N,{label:c.tenant,hint:c.tenantHint,children:e("input",{name:"tenantId","aria-label":"tenant_id",defaultValue:d,required:!0,style:i.input})}),e(N,{label:s.appKey,hint:s.hintAppKey,children:e("input",{name:"appKey","aria-label":"app_key",required:!0,style:i.input})}),e(N,{label:s.resourceKey,hint:s.hintResourceKey,children:e("input",{name:"resourceKey","aria-label":"resource_key",required:!0,style:i.input})}),e(N,{label:s.name,children:e("input",{name:"name","aria-label":"name",required:!0,style:i.input})}),e(N,{label:s.description,hint:c.optional,children:e("input",{name:"description","aria-label":"description",style:i.input})}),e("button",{type:"submit",style:i.primary,children:c.add})]})]})}function At({g:t,tenantId:n,labels:d}){let s=d.common,[c,p]=V({label:t.action,value:t.action});return u("tr",{children:[e(me,{tenantId:n,testId:`tenant-grant-${t.id}`}),e("td",{style:i.td,children:e("span",{style:i.code,children:t.roleKey})}),e("td",{style:i.td,children:u("span",{style:i.code,children:[t.appKey,":",t.resourceKey]})}),e("td",{style:i.td,children:t.roleKey==="@anonymous"?e("span",{style:i.code,children:t.action}):u(Pe,{children:[e("input",{type:"hidden",name:"action",value:c.value,form:`save-grant-${t.id}`}),e(ne,{options:Fe.map(x=>({label:x,value:x})),value:c,onChange:x=>{x&&p(x)}})]})}),e("td",{style:i.td,children:e("textarea",{name:"rowScope",defaultValue:t.rowScope??"",form:`save-grant-${t.id}`,"aria-label":`row_scope-${t.id}`,rows:2,placeholder:d.grants.rowScopePlaceholder,style:i.textarea})}),e("td",{style:i.td,children:e("textarea",{name:"columnScope",defaultValue:t.columnScope??"",form:`save-grant-${t.id}`,"aria-label":`column_scope-${t.id}`,rows:2,placeholder:d.grants.columnScopePlaceholder,style:i.textarea})}),u("td",{style:{...i.td,whiteSpace:"nowrap"},children:[u(B,{method:"post",id:`save-grant-${t.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:t.id}),e("button",{type:"submit",style:i.save,children:s.save})]}),u(B,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:t.id}),e("button",{type:"submit",style:i.danger,children:s.delete})]})]})]})}function Rt(){let{grants:t,roles:n,resources:d,labels:s,tenantId:c}=oe(),p=s.grants,x=s.common,o=n.map(z=>({label:z.roleKey,value:z.id})),I=d.map(z=>({label:`${z.appKey}:${z.resourceKey}`,value:z.id})),K=Fe.map(z=>({label:z,value:z})),[P,R]=V(void 0),[$,A]=V(void 0),[G,g]=V({label:"read",value:"read"});return u("section",{children:[e("h2",{style:i.h2,children:p.heading}),e("p",{style:i.note,children:p.note}),e(de,{message:pe(ce())}),e("div",{style:i.tableContainer,children:u("table",{style:i.table,children:[e("thead",{children:u("tr",{children:[e("th",{style:{...i.th,width:"10%"},children:x.tenant}),e("th",{style:{...i.th,width:"13%"},children:p.role}),e("th",{style:{...i.th,width:"17%"},children:p.resource}),e("th",{style:{...i.th,width:"13%"},children:p.action}),e("th",{style:{...i.th,width:"19%"},children:p.rowScope}),e("th",{style:{...i.th,width:"18%"},children:p.columnScope}),e("th",{style:{...i.th,width:"10%"}})]})}),u("tbody",{children:[t.map(z=>e(At,{g:z,tenantId:ke(n,z.roleId,s),labels:s},z.id)),t.length===0?e("tr",{children:e("td",{style:i.empty,colSpan:7,children:p.empty})}):null]})]})}),e("h3",{style:i.h3,children:p.newHeading}),u(B,{method:"post",style:i.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e("input",{type:"hidden",name:"roleId",value:P?.value??""}),e("input",{type:"hidden",name:"resourceId",value:$?.value??""}),e("input",{type:"hidden",name:"action",value:G?.value??""}),e(N,{label:x.tenant,hint:x.tenantHint,children:e("input",{name:"tenantId","aria-label":"tenant_id",defaultValue:c,required:!0,style:i.input})}),e(N,{label:p.role,children:e(ne,{options:o,value:P,onChange:z=>R(z||void 0),placeholder:p.selectPlaceholder})}),e(N,{label:p.resource,children:e(ne,{options:I,value:$,onChange:z=>A(z||void 0),placeholder:p.selectPlaceholder})}),e(N,{label:p.action,children:e(ne,{options:K,value:G,onChange:z=>g(z||void 0)})}),e(N,{label:p.rowScope,hint:p.rowScopeHint,children:e("textarea",{name:"rowScope","aria-label":"row_scope",rows:2,style:i.textarea,placeholder:'{"filters":[{"field":"\u90E8\u9580CD","op":"in","values":["A"]}]}'})}),e(N,{label:p.columnScope,hint:p.columnScopeHint,children:e("textarea",{name:"columnScope","aria-label":"column_scope",rows:2,style:i.textarea,placeholder:'{"mode":"deny","columns":["\u91D1\u984D"]}'})}),e("button",{type:"submit",style:i.primary,children:x.grant})]})]})}function St(){let{assignments:t,roles:n,users:d,actorUserId:s,selfAdminRoleIds:c,labels:p}=oe(),x=p.userRoles,o=p.common,I=new Set(c??[]),K=d.map(g=>({label:`${g.email}\uFF08${g.displayName}\uFF09`,value:g.id})),P=n.filter(g=>g.roleKey!=="@authenticated"&&g.roleKey!=="@anonymous").map(g=>({label:g.roleKey,value:g.id})),[R,$]=V(void 0),[A,G]=V(void 0);return u("section",{children:[e("h2",{style:i.h2,children:x.heading}),e(de,{message:pe(ce())}),e("p",{style:i.note,children:x.note}),e("div",{style:i.tableContainer,children:u("table",{style:i.table,children:[e("thead",{children:u("tr",{children:[e("th",{style:{...i.th,width:"12%"},children:o.tenant}),e("th",{style:{...i.th,width:"40%"},children:x.user}),e("th",{style:{...i.th,width:"38%"},children:x.role}),e("th",{style:{...i.th,width:"10%"}})]})}),u("tbody",{children:[t.map(g=>u("tr",{children:[e(me,{tenantId:ke(n,g.roleId,p),testId:`tenant-assignment-${g.userId}-${g.roleId}`}),u("td",{style:i.td,children:[g.email,u("span",{style:i.muted,children:["\uFF08",g.displayName,"\uFF09"]})]}),e("td",{style:i.td,children:g.roleKey}),e("td",{style:i.td,children:u(B,{method:"post",style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"remove"}),e("input",{type:"hidden",name:"userId",value:g.userId}),e("input",{type:"hidden",name:"roleId",value:g.roleId}),e("button",{type:"submit",style:i.danger,onClick:Se(g.userId===s&&I.has(g.roleId),p.warn.selfAssignmentRemove),children:o.remove})]})})]},`${g.userId}-${g.roleId}`)),t.length===0?e("tr",{children:e("td",{style:i.empty,colSpan:4,children:x.empty})}):null]})]})}),e("h3",{style:i.h3,children:x.newHeading}),u(B,{method:"post",style:i.card,children:[e("input",{type:"hidden",name:"_action",value:"assign"}),e("input",{type:"hidden",name:"userId",value:R?.value??""}),e("input",{type:"hidden",name:"roleId",value:A?.value??""}),e(N,{label:x.user,children:e(ne,{options:K,value:R,onChange:g=>$(g||void 0),placeholder:x.selectPlaceholder})}),e(N,{label:x.role,children:e(ne,{options:P,value:A,onChange:g=>G(g||void 0),placeholder:x.selectPlaceholder})}),e("button",{type:"submit",style:i.primary,children:o.assign})]})]})}function zt(){let{groupRoles:t,roles:n,groups:d,labels:s}=oe(),c=ce(),p=pe(c),x=s.groupRoles,o=s.common,I=n.filter(g=>g.isActive&&g.roleKey!=="@authenticated"&&g.roleKey!=="@anonymous"),K=d.map(g=>({label:`${g.name} (${g.groupKey})`,value:g.id})),P=I.map(g=>({label:`${g.name} (${g.roleKey})`,value:g.id})),[R,$]=V(K[0]),[A,G]=V(P[0]);return u("section",{style:{display:"flex",flexDirection:"column",gap:"1.25rem"},children:[u("div",{children:[e("h2",{style:i.h2,children:x.heading}),e("p",{style:i.note,children:x.note})]}),p&&e(de,{message:p}),u("table",{style:i.table,children:[e("thead",{children:u("tr",{children:[e("th",{style:{...i.th,width:"12%"},children:o.tenant}),e("th",{style:i.th,children:x.group}),e("th",{style:i.th,children:x.role}),e("th",{style:{...i.th,width:"100px"}})]})}),e("tbody",{children:t.length===0?e("tr",{children:e("td",{colSpan:4,style:{...i.td,textAlign:"center",color:"#64748b"},children:x.empty})}):t.map(g=>u("tr",{children:[e(me,{tenantId:ke(n,g.roleId,s),testId:`tenant-group-role-${g.groupId}-${g.roleId}`}),u("td",{style:i.td,children:[e("strong",{children:g.groupName})," ",u("span",{style:{color:"#64748b",fontSize:"0.85rem"},children:["(",g.groupKey,")"]})]}),e("td",{style:i.td,children:e("code",{children:g.roleKey})}),e("td",{style:{...i.td,textAlign:"right"},children:u(B,{method:"post",onSubmit:z=>!confirm("\u3053\u306E\u30B0\u30EB\u30FC\u30D7\u30ED\u30FC\u30EB\u5272\u5F53\u3092\u89E3\u9664\u3057\u307E\u3059\u304B\uFF1F")&&z.preventDefault(),children:[e("input",{type:"hidden",name:"_action",value:"remove"}),e("input",{type:"hidden",name:"groupId",value:g.groupId}),e("input",{type:"hidden",name:"roleId",value:g.roleId}),e("button",{type:"submit",style:i.danger,children:o.remove})]})})]},`${g.groupId}-${g.roleId}`))})]}),u(B,{method:"post",style:i.card,children:[e("h3",{style:i.h3,children:x.newHeading}),e("input",{type:"hidden",name:"_action",value:"assign"}),e("input",{type:"hidden",name:"groupId",value:R?.value??""}),e("input",{type:"hidden",name:"roleId",value:A?.value??""}),e(N,{label:x.group,children:e(ne,{options:K,value:R,onChange:g=>$(g||void 0),placeholder:x.selectPlaceholder})}),e(N,{label:x.role,children:e(ne,{options:P,value:A,onChange:g=>G(g||void 0),placeholder:x.selectPlaceholder})}),e("button",{type:"submit",style:i.primary,children:o.assign})]})]})}var ze={read:{bg:"#ecfdf5",text:"#047857",border:"#a7f3d0"},create:{bg:"#eff6ff",text:"#1d4ed8",border:"#bfdbfe"},update:{bg:"#fffbeb",text:"#b45309",border:"#fde68a"},delete:{bg:"#fef2f2",text:"#b91c1c",border:"#fecaca"}};function Pt({users:t,roles:n,resources:d,grants:s,assignments:c,groupRoles:p=[],groups:x=[],selectedNode:o,onNodeClick:I}){let[K,P]=V(null),R=new Set(c.map(r=>r.userId)),$=new Set(p.map(r=>r.groupId)),A=new Set([...c.map(r=>r.roleId),...p.map(r=>r.roleId),...s.map(r=>r.roleId)]),G=new Set(s.map(r=>r.resourceId)),g=t.filter(r=>R.has(r.id)),z=x.filter(r=>$.has(r.id)),M=n.filter(r=>A.has(r.id)),O=d.filter(r=>G.has(r.id)),re=r=>{let h=s.filter(b=>b.resourceId===r),m=Array.from(new Set(h.map(b=>b.action)));return m.length>0?m:["none"]},ae=r=>32+re(r).length*24+6,a=16,l=0,S=new Map;O.forEach(r=>{let h=re(r.id),m=ae(r.id),b=l,W=new Map;h.forEach((F,q)=>{let _=b+8+24+q*24+12;W.set(F,_)}),S.set(r.id,{top:b,height:m,actionYMap:W}),l+=m+a});let f=l>0?l-a:0,v=52,T=18,L=v+T,E=M.length>0?M.length*L-T:0,Z=z.length>0?z.length*L-T:0,Q=g.length>0?g.length*L-T:0,k=Math.max(f,E,Z,Q,320)+60,C=(k-f)/2,j=(k-E)/2,D=(k-Z)/2,ee=(k-Q)/2,Y=(r,h)=>{let m=S.get(r);if(!m)return k/2;let b=m.actionYMap.get(h)??m.height/2;return C+b},fe=r=>j+r*L+v/2,Ce=r=>D+r*L+v/2,$e=r=>ee+r*L+v/2,xe=140,se=420,ve=700,we=980,w=K||o,Ye=r=>{if(!w)return!0;if(w.type==="user")return w.id===r;if(w.type==="role")return c.some(h=>h.userId===r&&h.roleId===w.id);if(w.type==="group")return!1;if(w.type==="resource"){let h=s.filter(m=>m.resourceId===w.id).map(m=>m.roleId);return c.some(m=>m.userId===r&&h.includes(m.roleId))}return!0},Xe=r=>{if(!w)return!0;if(w.type==="group")return w.id===r;if(w.type==="role")return p.some(h=>h.groupId===r&&h.roleId===w.id);if(w.type==="user")return!1;if(w.type==="resource"){let h=s.filter(m=>m.resourceId===w.id).map(m=>m.roleId);return p.some(m=>m.groupId===r&&h.includes(m.roleId))}return!0},Qe=r=>w?w.type==="role"?w.id===r:w.type==="user"?c.some(h=>h.userId===w.id&&h.roleId===r):w.type==="group"?p.some(h=>h.groupId===w.id&&h.roleId===r):w.type==="resource"?s.some(h=>h.resourceId===w.id&&h.roleId===r):!0:!0,Je=r=>{if(!w)return!0;if(w.type==="resource")return w.id===r;if(w.type==="role")return s.some(h=>h.roleId===w.id&&h.resourceId===r);if(w.type==="group"){let h=p.filter(m=>m.groupId===w.id).map(m=>m.roleId);return s.some(m=>h.includes(m.roleId)&&m.resourceId===r)}if(w.type==="user"){let h=c.filter(m=>m.userId===w.id).map(m=>m.roleId);return s.some(m=>h.includes(m.roleId)&&m.resourceId===r)}return!0},Ze=(r,h)=>w?w.type==="user"?w.id===r&&c.some(m=>m.userId===r&&m.roleId===h):w.type==="role"?w.id===h&&c.some(m=>m.userId===r&&m.roleId===h):w.type==="resource"?s.filter(b=>b.resourceId===w.id).map(b=>b.roleId).includes(h)&&c.some(b=>b.userId===r&&b.roleId===h):w.type!=="group":!0,et=(r,h)=>w?w.type==="group"?w.id===r&&p.some(m=>m.groupId===r&&m.roleId===h):w.type==="role"?w.id===h&&p.some(m=>m.groupId===r&&m.roleId===h):w.type==="resource"?s.filter(b=>b.resourceId===w.id).map(b=>b.roleId).includes(h)&&p.some(b=>b.groupId===r&&b.roleId===h):w.type!=="user":!0,tt=(r,h)=>w?w.type==="role"?w.id===r&&s.some(m=>m.roleId===r&&m.resourceId===h):w.type==="resource"?w.id===h&&s.some(m=>m.roleId===r&&m.resourceId===h):w.type==="group"?p.filter(b=>b.groupId===w.id).map(b=>b.roleId).includes(r)&&s.some(b=>b.roleId===r&&b.resourceId===h):w.type==="user"?c.filter(b=>b.userId===w.id).map(b=>b.roleId).includes(r)&&s.some(b=>b.roleId===r&&b.resourceId===h):!0:!0,Te=[];c.forEach(r=>{let h=g.findIndex(b=>b.id===r.userId),m=M.findIndex(b=>b.id===r.roleId);if(h!==-1&&m!==-1){let b=c.filter(_=>_.roleId===r.roleId),W=b.findIndex(_=>_.userId===r.userId&&_.roleId===r.roleId),F=b.length,q=F>1?Math.min(Math.max((W-(F-1)/2)*4,-16),16):0;Te.push({uIdx:h,rIdx:m,active:Ze(r.userId,r.roleId),key:`ur-${r.userId}-${r.roleId}`,offset:q})}});let Ge=[];p.forEach(r=>{let h=z.findIndex(b=>b.id===r.groupId),m=M.findIndex(b=>b.id===r.roleId);if(h!==-1&&m!==-1){let b=p.filter(_=>_.roleId===r.roleId),W=b.findIndex(_=>_.groupId===r.groupId&&_.roleId===r.roleId),F=b.length,q=F>1?Math.min(Math.max((W-(F-1)/2)*4,-16),16):0;Ge.push({gIdx:h,rIdx:m,active:et(r.groupId,r.roleId),key:`gr-${r.groupId}-${r.roleId}`,offset:q})}});let Le=[];return s.forEach(r=>{let h=M.findIndex(b=>b.id===r.roleId),m=O.findIndex(b=>b.id===r.resourceId);if(h!==-1&&m!==-1){let b=s.filter(ye=>ye.resourceId===r.resourceId&&ye.action===r.action),W=b.findIndex(ye=>ye.id===r.id),F=b.length,q=F>1?Math.min(Math.max((W-(F-1)/2)*4,-12),12):0,_=ze[r.action],rt=_?_.text:"#6366f1";Le.push({rIdx:h,resIdx:m,active:tt(r.roleId,r.resourceId),key:`rr-grant-${r.id}`,action:r.action,color:rt,offset:q})}}),e("div",{"data-testid":"authz-topology-map",style:{width:"100%",overflowX:"auto",backgroundColor:"#ffffff",borderRadius:"10px",border:"1px solid #e2e8f0",padding:"1rem",boxSizing:"border-box"},children:u("div",{style:{position:"relative",minWidth:"1160px",height:`${k}px`},children:[u("svg",{style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",pointerEvents:"none",zIndex:1},children:[e("title",{children:"Topology Connections"}),Le.map(r=>{let h=s.find(q=>`rr-grant-${q.id}`===r.key);if(!h)return null;let m=Y(h.resourceId,h.action)+r.offset,b=fe(r.rIdx),W=xe+135,F=se-135;return e("path",{d:`M ${xe+90} ${m} C ${W} ${m}, ${F} ${b}, ${se-90} ${b}`,fill:"none",stroke:r.active?r.color:"#cbd5e1",strokeWidth:r.active&&w?3:2,strokeOpacity:r.active?w?1:.75:.12,style:{transition:"all 0.2s ease"}},r.key)}),Ge.map(r=>{let h=fe(r.rIdx)+r.offset,m=Ce(r.gIdx),b=se+135,W=ve-135;return e("path",{"data-testid":`topo-link-group-role-${r.key}`,"data-active":r.active?"true":"false",d:`M ${se+90} ${h} C ${b} ${h}, ${W} ${m}, ${ve-90} ${m}`,fill:"none",stroke:r.active?"#8b5cf6":"#cbd5e1",strokeWidth:r.active&&w?3:2,strokeDasharray:"4 2",strokeOpacity:r.active?w?1:.75:.12,style:{transition:"all 0.2s ease"}},r.key)}),Te.map(r=>{let h=fe(r.rIdx)+r.offset,m=$e(r.uIdx),b=se+135,W=we-135;return e("path",{"data-testid":`topo-link-user-role-${r.key}`,"data-active":r.active?"true":"false",d:`M ${se+90} ${h} C ${b} ${h}, ${W} ${m}, ${we-90} ${m}`,fill:"none",stroke:r.active?"#4f46e5":"#cbd5e1",strokeWidth:r.active&&w?3:2,strokeOpacity:r.active?w?1:.75:.12,style:{transition:"all 0.2s ease"}},r.key)})]}),u("div",{style:{position:"relative",zIndex:2,width:"100%",height:"100%"},children:[O.map(r=>{let h=o?.type==="resource"&&o.id===r.id,m=Je(r.id),b=S.get(r.id);if(!b)return null;let W=C+b.top,F=re(r.id);return u("div",{style:{position:"absolute",left:`${xe-90}px`,top:`${W}px`,width:"180px",height:`${b.height}px`,borderRadius:"8px",border:h?"2px solid #10b981":"1px solid #a7f3d0",backgroundColor:h?"#d1fae5":m?"#ffffff":"#f8fafc",opacity:m?1:.35,boxShadow:h?"0 4px 12px rgba(16, 185, 129, 0.2)":"0 1px 3px rgba(0,0,0,0.05)",transition:"all 0.15s ease",padding:"8px",boxSizing:"border-box",display:"flex",flexDirection:"column"},children:[u("button",{type:"button",onClick:()=>I("resource",r.id),onMouseEnter:()=>P({type:"resource",id:r.id}),onMouseLeave:()=>P(null),"data-testid":`topo-node-resource-${r.id}`,"aria-label":`\u30EA\u30BD\u30FC\u30B9: ${r.name}`,"aria-pressed":h,style:{background:"none",border:"none",padding:0,margin:0,cursor:"pointer",textAlign:"left",width:"100%",display:"flex",alignItems:"center",gap:"6px",marginBottom:"6px",height:"18px"},children:[e("span",{style:{fontSize:"1rem",flexShrink:0},children:"\u{1F511}"}),e("span",{style:{fontWeight:600,fontSize:"0.78rem",color:"#047857",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:r.name})]}),e("div",{style:{display:"flex",flexDirection:"column",gap:"2px"},children:F.map(q=>{if(q==="none")return e("div",{style:{fontSize:"0.68rem",color:"#94a3b8",height:"22px",display:"flex",alignItems:"center",padding:"0 6px"},children:"\u6A29\u9650\u8A2D\u5B9A\u306A\u3057"},"none");let _=ze[q]??{bg:"#ecfdf5",text:"#047857",border:"#a7f3d0"};return u("div",{style:{height:"22px",boxSizing:"border-box",padding:"0 8px",borderRadius:"4px",backgroundColor:_.bg,color:_.text,border:`1px solid ${_.border}`,display:"flex",alignItems:"center",justifyContent:"space-between",fontSize:"0.68rem",fontWeight:600},children:[e("span",{children:q}),e("span",{style:{fontSize:"0.6rem",opacity:.6},children:"\u25CF"})]},q)})})]},r.id)}),M.map((r,h)=>{let m=o?.type==="role"&&o.id===r.id,b=Qe(r.id),W=fe(h);return u("button",{type:"button",onClick:()=>I("role",r.id),onMouseEnter:()=>P({type:"role",id:r.id}),onMouseLeave:()=>P(null),"data-testid":`topo-node-role-${r.id}`,"aria-label":`\u30ED\u30FC\u30EB: ${r.name}`,"aria-pressed":m,style:{position:"absolute",left:`${se-90}px`,top:`${W-26}px`,width:"180px",height:"52px",borderRadius:"8px",border:m?"2px solid #6366f1":"1px solid #c7d2fe",backgroundColor:m?"#e0e7ff":b?"#ffffff":"#f8fafc",opacity:b?1:.35,cursor:"pointer",display:"flex",alignItems:"center",padding:"0 10px",gap:"8px",boxShadow:m?"0 4px 12px rgba(99, 102, 241, 0.2)":"0 1px 3px rgba(0,0,0,0.05)",transition:"all 0.15s ease",textAlign:"left",boxSizing:"border-box"},children:[e("span",{style:{fontSize:"1.1rem",flexShrink:0},children:"\u{1F6E1}\uFE0F"}),u("div",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flex:1,minWidth:0},children:[e("div",{style:{fontWeight:600,fontSize:"0.78rem",color:"#4338ca",textOverflow:"ellipsis",overflow:"hidden"},children:r.name}),e("div",{style:{fontSize:"0.68rem",color:"#64748b",fontFamily:"monospace",textOverflow:"ellipsis",overflow:"hidden"},children:r.roleKey})]})]},r.id)}),z.map((r,h)=>{let m=o?.type==="group"&&o.id===r.id,b=Xe(r.id),W=Ce(h);return u("button",{type:"button",onClick:()=>I("group",r.id),onMouseEnter:()=>P({type:"group",id:r.id}),onMouseLeave:()=>P(null),"data-testid":`topo-node-group-${r.id}`,"aria-label":`\u30B0\u30EB\u30FC\u30D7: ${r.name}`,"aria-pressed":m,style:{position:"absolute",left:`${ve-90}px`,top:`${W-26}px`,width:"180px",height:"52px",borderRadius:"8px",border:m?"2px solid #8b5cf6":"1px solid #ddd6fe",backgroundColor:m?"#f3e8ff":b?"#ffffff":"#f8fafc",opacity:b?1:.35,cursor:"pointer",display:"flex",alignItems:"center",padding:"0 10px",gap:"8px",boxShadow:m?"0 4px 12px rgba(139, 92, 246, 0.2)":"0 1px 3px rgba(0,0,0,0.05)",transition:"all 0.15s ease",textAlign:"left",boxSizing:"border-box"},children:[e("span",{style:{fontSize:"1.1rem",flexShrink:0},children:"\u{1F465}"}),u("div",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flex:1,minWidth:0},children:[e("div",{style:{fontWeight:600,fontSize:"0.78rem",color:"#6d28d9",textOverflow:"ellipsis",overflow:"hidden"},children:r.name}),e("div",{style:{fontSize:"0.68rem",color:"#64748b",fontFamily:"monospace",textOverflow:"ellipsis",overflow:"hidden"},children:r.groupKey})]})]},r.id)}),g.map((r,h)=>{let m=o?.type==="user"&&o.id===r.id,b=Ye(r.id),W=$e(h);return u("button",{type:"button",onClick:()=>I("user",r.id),onMouseEnter:()=>P({type:"user",id:r.id}),onMouseLeave:()=>P(null),"data-testid":`topo-node-user-${r.id}`,"aria-label":`\u30E6\u30FC\u30B6\u30FC: ${r.displayName}`,"aria-pressed":m,style:{position:"absolute",left:`${we-90}px`,top:`${W-26}px`,width:"180px",height:"52px",borderRadius:"8px",border:m?"2px solid #0284c7":"1px solid #bae6fd",backgroundColor:m?"#e0f2fe":b?"#ffffff":"#f8fafc",opacity:b?1:.35,cursor:"pointer",display:"flex",alignItems:"center",padding:"0 10px",gap:"8px",boxShadow:m?"0 4px 12px rgba(2, 132, 199, 0.2)":"0 1px 3px rgba(0,0,0,0.05)",transition:"all 0.15s ease",textAlign:"left",boxSizing:"border-box"},children:[e("span",{style:{fontSize:"1.1rem",flexShrink:0},children:"\u{1F464}"}),u("div",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flex:1,minWidth:0},children:[e("div",{style:{fontWeight:600,fontSize:"0.78rem",color:"#0369a1",textOverflow:"ellipsis",overflow:"hidden"},children:r.displayName}),e("div",{style:{fontSize:"0.68rem",color:"#64748b",textOverflow:"ellipsis",overflow:"hidden"},children:r.email})]})]},r.id)})]})]})})}function kt(){let{users:t,roles:n,resources:d,grants:s,assignments:c,groupRoles:p=[],groups:x=[]}=oe(),[o,I]=V(null),[K,P]=V(""),[R,$]=V("topology"),A=new Map(n.map(y=>[y.id,y])),G=new Map(d.map(y=>[y.id,y])),g=new Map(x.map(y=>[y.id,y])),z=new Map(t.map(y=>[y.id,y])),M=y=>{if(!o)return!0;if(o.type==="user")return o.id===y;if(o.type==="role")return c.some(k=>k.userId===y&&k.roleId===o.id);if(o.type==="group")return!1;if(o.type==="resource"){let k=s.filter(C=>C.resourceId===o.id).map(C=>C.roleId);return c.some(C=>C.userId===y&&k.includes(C.roleId))}return!0},O=y=>{if(!o)return!0;if(o.type==="group")return o.id===y;if(o.type==="role")return p.some(k=>k.groupId===y&&k.roleId===o.id);if(o.type==="user")return!1;if(o.type==="resource"){let k=s.filter(C=>C.resourceId===o.id).map(C=>C.roleId);return p.some(C=>C.groupId===y&&k.includes(C.roleId))}return!0},re=y=>o?o.type==="role"?o.id===y:o.type==="user"?c.some(k=>k.userId===o.id&&k.roleId===y):o.type==="group"?p.some(k=>k.groupId===o.id&&k.roleId===y):o.type==="resource"?s.some(k=>k.resourceId===o.id&&k.roleId===y):!0:!0,ae=y=>{if(!o)return!0;if(o.type==="resource")return o.id===y;if(o.type==="role")return s.some(k=>k.roleId===o.id&&k.resourceId===y);if(o.type==="group"){let k=p.filter(C=>C.groupId===o.id).map(C=>C.roleId);return s.some(C=>k.includes(C.roleId)&&C.resourceId===y)}if(o.type==="user"){let k=c.filter(C=>C.userId===o.id).map(C=>C.roleId);return s.some(C=>k.includes(C.roleId)&&C.resourceId===y)}return!0},a=K.trim().toLowerCase(),l=t.filter(y=>!a||y.displayName.toLowerCase().includes(a)||y.email?.toLowerCase().includes(a)),S=x.filter(y=>!a||y.name.toLowerCase().includes(a)||y.groupKey.toLowerCase().includes(a)),f=n.filter(y=>!a||y.name.toLowerCase().includes(a)||y.roleKey.toLowerCase().includes(a)),v=d.filter(y=>!a||y.name.toLowerCase().includes(a)||y.resourceKey.toLowerCase().includes(a)||y.appKey.toLowerCase().includes(a)),T=o?.type==="user"?z.get(o.id):null,L=o?.type==="group"?g.get(o.id):null,E=o?.type==="role"?A.get(o.id):null,Z=o?.type==="resource"?G.get(o.id):null,Q=(y,k)=>{o&&o.type===y&&o.id===k?I(null):I({type:y,id:k})};return u("section",{"data-testid":"authz-graph-view",style:{display:"flex",flexDirection:"column",gap:"1rem",width:"100%"},children:[u("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",flexWrap:"wrap",gap:"0.75rem",backgroundColor:"#f8fafc",padding:"0.75rem 1rem",borderRadius:"8px",border:"1px solid #e2e8f0",width:"100%",boxSizing:"border-box"},children:[u("div",{style:{display:"flex",alignItems:"center",gap:"0.75rem",flexWrap:"wrap"},children:[u("div",{style:{display:"inline-flex",borderRadius:"6px",border:"1px solid #cbd5e1",padding:"2px",backgroundColor:"#ffffff"},children:[e("button",{type:"button",onClick:()=>$("topology"),"data-testid":"switch-mode-topology",style:{padding:"3px 10px",borderRadius:"4px",border:"none",cursor:"pointer",fontSize:"0.75rem",fontWeight:R==="topology"?600:400,backgroundColor:R==="topology"?"#eff6ff":"transparent",color:R==="topology"?"#0284c7":"#64748b",boxShadow:R==="topology"?"0 1px 2px rgba(0,0,0,0.08)":"none"},children:"\u{1F310} \u30C8\u30DD\u30ED\u30B8\u30DE\u30C3\u30D7 (Topology)"}),e("button",{type:"button",onClick:()=>$("columns"),"data-testid":"switch-mode-columns",style:{padding:"3px 10px",borderRadius:"4px",border:"none",cursor:"pointer",fontSize:"0.75rem",fontWeight:R==="columns"?600:400,backgroundColor:R==="columns"?"#eff6ff":"transparent",color:R==="columns"?"#0284c7":"#64748b",boxShadow:R==="columns"?"0 1px 2px rgba(0,0,0,0.08)":"none"},children:"\u{1F4CB} \u30AB\u30E9\u30E0\u4E00\u89A7 (Columns)"})]}),u("div",{style:{display:"flex",gap:"0.4rem",fontSize:"0.75rem",flexWrap:"wrap"},children:[u("span",{style:{backgroundColor:"#e0f2fe",color:"#0369a1",padding:"2px 8px",borderRadius:"12px",fontWeight:600},children:["\u{1F464} \u30E6\u30FC\u30B6\u30FC: ",t.length]}),u("span",{style:{backgroundColor:"#f3e8ff",color:"#6d28d9",padding:"2px 8px",borderRadius:"12px",fontWeight:600},children:["\u{1F465} \u30B0\u30EB\u30FC\u30D7: ",x.length]}),u("span",{style:{backgroundColor:"#e0e7ff",color:"#4338ca",padding:"2px 8px",borderRadius:"12px",fontWeight:600},children:["\u{1F6E1}\uFE0F \u30ED\u30FC\u30EB: ",n.length]}),u("span",{style:{backgroundColor:"#d1fae5",color:"#047857",padding:"2px 8px",borderRadius:"12px",fontWeight:600},children:["\u{1F511} \u30EA\u30BD\u30FC\u30B9: ",d.length]}),u("span",{style:{backgroundColor:"#fef3c7",color:"#b45309",padding:"2px 8px",borderRadius:"12px",fontWeight:600},children:["\u26A1\uFE0F \u6A29\u9650\u8A2D\u5B9A: ",s.length]})]})]}),e("div",{style:{display:"flex",alignItems:"center",gap:"0.5rem"},children:e("input",{type:"text",placeholder:"\u30AD\u30FC\u30EF\u30FC\u30C9\u3067\u7D5E\u308A\u8FBC\u307F...",value:K,onChange:y=>P(y.target.value),"data-testid":"graph-search-input",style:{padding:"5px 10px",borderRadius:"6px",border:"1px solid #cbd5e1",fontSize:"0.8rem",width:"200px"}})})]}),u("div",{style:{minHeight:"38px",height:"38px",display:"flex",alignItems:"center",justifyContent:"space-between",backgroundColor:o?"#eff6ff":"#f8fafc",border:`1px solid ${o?"#bfdbfe":"#e2e8f0"}`,padding:"0 0.8rem",borderRadius:"6px",fontSize:"0.8rem",color:o?"#1e40af":"#64748b",width:"100%",boxSizing:"border-box",transition:"all 0.15s ease"},children:[e("div",{style:{display:"flex",alignItems:"center",gap:"0.4rem",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:o?u(Pe,{children:[e("span",{children:"\u{1F3AF}"}),e("strong",{children:"\u9078\u629E\u4E2D\u306E\u30CE\u30FC\u30C9:"}),u("span",{children:[T&&`\u30E6\u30FC\u30B6\u30FC\u300C${T.displayName} (${T.email})\u300D\u306B\u95A2\u9023\u3059\u308B\u30D1\u30B9\u3092\u8868\u793A\u4E2D`,L&&`\u30B0\u30EB\u30FC\u30D7\u300C${L.name} (${L.groupKey})\u300D\u306B\u95A2\u9023\u3059\u308B\u30D1\u30B9\u3092\u8868\u793A\u4E2D`,E&&`\u30ED\u30FC\u30EB\u300C${E.name} (${E.roleKey})\u300D\u306B\u95A2\u9023\u3059\u308B\u30D1\u30B9\u3092\u8868\u793A\u4E2D`,Z&&`\u30EA\u30BD\u30FC\u30B9\u300C${Z.name} (${Z.appKey}:${Z.resourceKey})\u300D\u306B\u95A2\u9023\u3059\u308B\u30D1\u30B9\u3092\u8868\u793A\u4E2D`]})]}):u(Pe,{children:[e("span",{children:"\u{1F4A1}"}),u("span",{children:[e("strong",{children:"\u30D2\u30F3\u30C8:"})," \u30CE\u30FC\u30C9\uFF08\u30EA\u30BD\u30FC\u30B9\u30FB\u30ED\u30FC\u30EB\u30FB\u30B0\u30EB\u30FC\u30D7\u30FB\u30E6\u30FC\u30B6\u30FC\uFF09\u3092\u30AF\u30EA\u30C3\u30AF\u3059\u308B\u3068\u3001\u95A2\u9023\u3059\u308B\u5168\u30D1\u30B9\u304C\u30CF\u30A4\u30E9\u30A4\u30C8\u8868\u793A\u3055\u308C\u307E\u3059"]})]})}),o&&e("button",{type:"button",onClick:()=>I(null),"data-testid":"graph-reset-selection",style:{padding:"3px 8px",borderRadius:"4px",border:"1px solid #93c5fd",backgroundColor:"#ffffff",fontSize:"0.72rem",cursor:"pointer",color:"#1d4ed8",fontWeight:600,whiteSpace:"nowrap",boxShadow:"0 1px 2px rgba(0,0,0,0.05)"},children:"\u2715 \u9078\u629E\u89E3\u9664"})]}),R==="topology"?e(Pt,{users:l,roles:f,resources:v,grants:s,assignments:c,groupRoles:p,groups:S,selectedNode:o,onNodeClick:Q}):u("div",{style:{display:"grid",gridTemplateColumns:"repeat(4, minmax(0, 1fr))",gap:"1rem",alignItems:"start",width:"100%",boxSizing:"border-box"},children:[u("div",{style:{backgroundColor:"#ffffff",borderRadius:"8px",border:"1px solid #e2e8f0",padding:"0.75rem"},children:[u("div",{style:{fontWeight:700,fontSize:"0.85rem",color:"#047857",marginBottom:"0.6rem",display:"flex",alignItems:"center",gap:"0.3rem",borderBottom:"2px solid #a7f3d0",paddingBottom:"0.4rem"},children:[e("span",{children:"\u{1F511}"})," \u30EA\u30BD\u30FC\u30B9 (",v.length,")"]}),u("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",maxHeight:"480px",overflowY:"auto",paddingRight:"4px"},children:[v.length===0&&e("div",{style:{fontSize:"0.8rem",color:"#94a3b8",textAlign:"center",padding:"1rem"},children:"\u5BFE\u8C61\u306E\u30EA\u30BD\u30FC\u30B9\u304C\u3042\u308A\u307E\u305B\u3093"}),v.map(y=>{let k=o?.type==="resource"&&o.id===y.id,C=ae(y.id),j=s.filter(D=>D.resourceId===y.id);return u("button",{type:"button",onClick:()=>Q("resource",y.id),"data-testid":`graph-node-resource-${y.id}`,style:{textAlign:"left",width:"100%",padding:"0.6rem",borderRadius:"6px",border:k?"2px solid #10b981":"1px solid #e2e8f0",backgroundColor:k?"#d1fae5":C?"#ffffff":"#f8fafc",opacity:C?1:.4,cursor:"pointer",transition:"all 0.15s ease",boxShadow:k?"0 2px 4px rgba(16, 185, 129, 0.15)":"none"},children:[e("div",{style:{fontWeight:600,fontSize:"0.82rem",color:"#0f172a"},children:y.name}),u("div",{style:{fontSize:"0.72rem",color:"#64748b",fontFamily:"monospace"},children:[y.appKey,":",y.resourceKey]}),u("div",{style:{display:"flex",flexWrap:"wrap",gap:"0.25rem",marginTop:"0.4rem"},children:[j.map(D=>{let ee=A.get(D.roleId),Y=ze[D.action]??{bg:"#f1f5f9",text:"#475569",border:"#cbd5e1"};return u("span",{style:{fontSize:"0.68rem",padding:"1px 6px",borderRadius:"4px",backgroundColor:Y.bg,color:Y.text,border:`1px solid ${Y.border}`},children:[ee?.roleKey??`Role#${D.roleId}`,": ",e("strong",{children:D.action})]},D.id)}),j.length===0&&e("span",{style:{fontSize:"0.68rem",color:"#94a3b8"},children:"\u6A29\u9650\u8A2D\u5B9A\u306A\u3057"})]})]},y.id)})]})]}),u("div",{style:{backgroundColor:"#ffffff",borderRadius:"8px",border:"1px solid #e2e8f0",padding:"0.75rem"},children:[u("div",{style:{fontWeight:700,fontSize:"0.85rem",color:"#4338ca",marginBottom:"0.6rem",display:"flex",alignItems:"center",gap:"0.3rem",borderBottom:"2px solid #c7d2fe",paddingBottom:"0.4rem"},children:[e("span",{children:"\u{1F6E1}\uFE0F"})," \u30ED\u30FC\u30EB (",f.length,")"]}),u("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",maxHeight:"480px",overflowY:"auto",paddingRight:"4px"},children:[f.length===0&&e("div",{style:{fontSize:"0.8rem",color:"#94a3b8",textAlign:"center",padding:"1rem"},children:"\u5BFE\u8C61\u306E\u30ED\u30FC\u30EB\u304C\u3042\u308A\u307E\u305B\u3093"}),f.map(y=>{let k=o?.type==="role"&&o.id===y.id,C=re(y.id),j=s.filter(Y=>Y.roleId===y.id),D=c.filter(Y=>Y.roleId===y.id),ee=p.filter(Y=>Y.roleId===y.id);return u("button",{type:"button",onClick:()=>Q("role",y.id),"data-testid":`graph-node-role-${y.id}`,style:{textAlign:"left",width:"100%",padding:"0.6rem",borderRadius:"6px",border:k?"2px solid #6366f1":"1px solid #e2e8f0",backgroundColor:k?"#e0e7ff":C?"#ffffff":"#f8fafc",opacity:C?1:.4,cursor:"pointer",transition:"all 0.15s ease",boxShadow:k?"0 2px 4px rgba(99, 102, 241, 0.15)":"none"},children:[e("div",{style:{fontWeight:600,fontSize:"0.82rem",color:"#0f172a"},children:y.name}),e("div",{style:{fontSize:"0.72rem",color:"#64748b",fontFamily:"monospace"},children:y.roleKey}),u("div",{style:{fontSize:"0.7rem",color:"#475569",marginTop:"0.3rem",display:"flex",gap:"0.5rem"},children:[u("span",{children:["\u6A29\u9650: ",j.length]}),u("span",{children:["\u30B0\u30EB\u30FC\u30D7: ",ee.length]}),u("span",{children:["\u30E6\u30FC\u30B6\u30FC: ",D.length]})]})]},y.id)})]})]}),u("div",{style:{backgroundColor:"#ffffff",borderRadius:"8px",border:"1px solid #e2e8f0",padding:"0.75rem"},children:[u("div",{style:{fontWeight:700,fontSize:"0.85rem",color:"#6d28d9",marginBottom:"0.6rem",display:"flex",alignItems:"center",gap:"0.3rem",borderBottom:"2px solid #ddd6fe",paddingBottom:"0.4rem"},children:[e("span",{children:"\u{1F465}"})," \u30B0\u30EB\u30FC\u30D7 (",S.length,")"]}),u("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",maxHeight:"480px",overflowY:"auto",paddingRight:"4px"},children:[S.length===0&&e("div",{style:{fontSize:"0.8rem",color:"#94a3b8",textAlign:"center",padding:"1rem"},children:"\u5BFE\u8C61\u306E\u30B0\u30EB\u30FC\u30D7\u304C\u3042\u308A\u307E\u305B\u3093"}),S.map(y=>{let k=o?.type==="group"&&o.id===y.id,C=O(y.id),j=p.filter(D=>D.groupId===y.id);return u("button",{type:"button",onClick:()=>Q("group",y.id),"data-testid":`graph-node-group-${y.id}`,style:{textAlign:"left",width:"100%",padding:"0.6rem",borderRadius:"6px",border:k?"2px solid #8b5cf6":"1px solid #e2e8f0",backgroundColor:k?"#f3e8ff":C?"#ffffff":"#f8fafc",opacity:C?1:.4,cursor:"pointer",transition:"all 0.15s ease",boxShadow:k?"0 2px 4px rgba(139, 92, 246, 0.15)":"none"},children:[e("div",{style:{fontWeight:600,fontSize:"0.82rem",color:"#0f172a"},children:y.name}),e("div",{style:{fontSize:"0.72rem",color:"#64748b",fontFamily:"monospace"},children:y.groupKey}),u("div",{style:{display:"flex",flexWrap:"wrap",gap:"0.25rem",marginTop:"0.4rem"},children:[j.map(D=>{let ee=A.get(D.roleId);return u("span",{style:{fontSize:"0.68rem",padding:"1px 6px",borderRadius:"4px",backgroundColor:"#f3e8ff",color:"#6d28d9",border:"1px solid #ddd6fe",fontWeight:600},children:["\u{1F6E1}\uFE0F ",ee?.name??D.roleKey]},`${D.groupId}-${D.roleId}`)}),j.length===0&&e("span",{style:{fontSize:"0.68rem",color:"#94a3b8"},children:"\u30ED\u30FC\u30EB\u672A\u5272\u308A\u5F53\u3066"})]})]},y.id)})]})]}),u("div",{style:{backgroundColor:"#ffffff",borderRadius:"8px",border:"1px solid #e2e8f0",padding:"0.75rem"},children:[u("div",{style:{fontWeight:700,fontSize:"0.85rem",color:"#0369a1",marginBottom:"0.6rem",display:"flex",alignItems:"center",gap:"0.3rem",borderBottom:"2px solid #bae6fd",paddingBottom:"0.4rem"},children:[e("span",{children:"\u{1F464}"})," \u30E6\u30FC\u30B6\u30FC (",l.length,")"]}),u("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",maxHeight:"480px",overflowY:"auto",paddingRight:"4px"},children:[l.length===0&&e("div",{style:{fontSize:"0.8rem",color:"#94a3b8",textAlign:"center",padding:"1rem"},children:"\u5BFE\u8C61\u306E\u30E6\u30FC\u30B6\u30FC\u304C\u3042\u308A\u307E\u305B\u3093"}),l.map(y=>{let k=o?.type==="user"&&o.id===y.id,C=M(y.id),j=c.filter(D=>D.userId===y.id);return u("button",{type:"button",onClick:()=>Q("user",y.id),"data-testid":`graph-node-user-${y.id}`,style:{textAlign:"left",width:"100%",padding:"0.6rem",borderRadius:"6px",border:k?"2px solid #0284c7":"1px solid #e2e8f0",backgroundColor:k?"#e0f2fe":C?"#ffffff":"#f8fafc",opacity:C?1:.4,cursor:"pointer",transition:"all 0.15s ease",boxShadow:k?"0 2px 4px rgba(2, 132, 199, 0.15)":"none"},children:[e("div",{style:{fontWeight:600,fontSize:"0.82rem",color:"#0f172a"},children:y.displayName}),e("div",{style:{fontSize:"0.72rem",color:"#64748b"},children:y.email}),u("div",{style:{display:"flex",flexWrap:"wrap",gap:"0.25rem",marginTop:"0.4rem"},children:[j.map(D=>{let ee=A.get(D.roleId);return u("span",{style:{fontSize:"0.68rem",padding:"1px 6px",borderRadius:"4px",backgroundColor:"#e0f2fe",color:"#0369a1",border:"1px solid #bae6fd",fontWeight:600},children:["\u{1F6E1}\uFE0F ",ee?.name??D.roleKey]},`${D.userId}-${D.roleId}`)}),j.length===0&&e("span",{style:{fontSize:"0.68rem",color:"#94a3b8"},children:"\u76F4\u63A5\u30ED\u30FC\u30EB\u306A\u3057"})]})]},y.id)})]})]})]})]})}var Kt={roles:He,resources:It,role_permissions:Rt,user_roles:St,group_roles:zt,graph:kt};function pr({renderHeader:t}={}){let{segment:n}=oe(),d=Kt[n]??He;return e(qe,{renderHeader:t,children:e(d,{})})}function yr(t){let n={};for(let d of Object.keys(t)){let s=t[d];n[d]={key:s.key??d,name:s.name,description:s.description}}return n}function gr(t){return Object.values(t).map(n=>n.key)}import{AUTHZ_ACTIONS as Be,assertTenantId as Ct,can as be,createRequirePermission as $t,isSameTenant as Tt}from"@aiquants/authz-core";import{redirect as Gt}from"react-router";var je="@aiquants/authz-react-router",X=class extends Error{constructor(n){super(`[${je}] ${n}`),this.name="AuthzUsageError"}};function Ke(t,n){let d=be(n,"read"),s=be(n,"create"),c=be(n,"update"),p=be(n,"delete"),x=n?.scopeByAction.read,o=d&&(!x||x.rowScope!==null||x.columnScope!==null);return{resourceKey:t,canRead:d,canCreate:s,canUpdate:c,canDelete:p,canWrite:s||c,readPartial:o,actions:n?Array.from(n.actions):[]}}function ie(t){return t===null?"null":typeof t=="string"?`a string (${JSON.stringify(t)})`:Array.isArray(t)?"an array":`${typeof t} (${String(t)})`}function Ve(t,n){if(!Array.isArray(t)){let c=typeof t=="string"?` A bare string would be iterated character by character; pass \`{ resourceKeys: [${JSON.stringify(t)}] }\` instead.`:"";throw new X(`${n} must be an array of resource keys, but received ${ie(t)}.${c}`)}let d=new Set,s=[];return t.forEach((c,p)=>{if(typeof c!="string"||c.trim()==="")throw new X(`${n}[${p}] must be a non-empty resource key string, but received ${ie(c)}.`);d.has(c)||(d.add(c),s.push(c))}),s}function Lt(t){if(t==null)return;let n=t;if(n.actions instanceof Set&&typeof n.scopeByAction=="object")throw new X("createAuthz({ getEffectivePermissions }) must resolve to a record keyed by resource key (e.g. getEffectivePermissionsMany from @aiquants/authz-drizzle), but it resolved to a single EffectivePermission. Keeping the single-resource port would deny every resource silently.")}function Dt(t){if(typeof t!="object"||t===null)throw new X(`requirePermission(request, query) requires a query object like { resourceKey: "documents", action: "read" }, but received ${ie(t)}.`);let{resourceKey:n,action:d}=t;if(typeof n!="string"||n.trim()==="")throw new X(`query.resourceKey must be a non-empty string, but received ${ie(n)}.`);if(typeof d!="string"||!Be.includes(d)){let s=d==="write"?' "write" is a derived concept (create \u222A update) and is never guarded directly \u2014 guard "create" or "update".':"";throw new X(`query.action must be one of ${Be.join(" | ")}, but received ${ie(d)}.${s}`)}return{resourceKey:n,action:d}}function Wt(t,n){return t!==null&&Tt(n,t.tenantId)?t:null}function vr(t){if(typeof t.resolveTenantId!="function")throw new X(`createAuthz({ resolveTenantId }) is required: every permission check is scoped to exactly one tenant, but received ${ie(t.resolveTenantId)}.`);if(typeof t.assertTenantMembership!="function")throw new X(`createAuthz({ assertTenantMembership }) is required: resolving a tenant only says which tenant the request named \u2014 it never proves the caller may act as it, so without this port naming another tenant is enough to be authorized inside it. Received ${ie(t.assertTenantMembership)}.`);async function n(o,I){return t.resolveGroupIds?await t.resolveGroupIds(o,I)??void 0:void 0}async function d(o){return Ct(await t.resolveTenantId(o),`${je} createAuthz(resolveTenantId)`)}async function s(o,I,K,P){if(I.length===0)return{};let R=await n(o,P),$=await t.getEffectivePermissions({userId:K,tenantId:P,groupIds:R,appKey:t.appKey,resourceKeys:I});return Lt($),Object.fromEntries(I.map(A=>[A,($&&Object.hasOwn($,A)?$[A]:null)??null]))}async function c(o,I,K){let{resourceKey:P,action:R}=Dt(I),$=K?.failureRedirect?()=>{throw Gt(K.failureRedirect)}:t.onDeny,G=await $t({resolveUserId:t.resolveUserId,resolveTenantId:d,assertTenantMembership:({ctx:g,tenantId:z,userId:M})=>t.assertTenantMembership(g,z,M),getEffectivePermissions:async g=>(await s(o,[g.resourceKey],g.userId,g.tenantId))[g.resourceKey],onDeny:$})(o,{appKey:t.appKey,resourceKey:P,action:R});return{userId:G.userId,tenantId:G.tenantId,scope:G.scope,permission:Ke(P,G.effectivePermission)}}function p(o){if(o?.resourceKeys!==void 0)return{kind:"explicit",keys:Ve(o.resourceKeys,"getMyPermissions options.resourceKeys")};if(!t.listResourceKeys)throw new X('getMyPermissions(request) needs to know which resources exist. Either pass them explicitly \u2014 getMyPermissions(request, { resourceKeys: ["documents"] }) \u2014 or configure createAuthz({ listResourceKeys }) (e.g. listResourceKeys from @aiquants/authz-drizzle) to report on every registered resource.');return{kind:"all",listResourceKeys:t.listResourceKeys}}async function x(o,I){let K=p(I),P=await t.resolveUserId(o)??null,R=await d(o);if(!await t.assertTenantMembership(o,R,P))return K.kind==="explicit"?Object.fromEntries(K.keys.map(G=>[G,Ke(G,null)])):{};let $=K.kind==="explicit"?K.keys:Ve(await K.listResourceKeys(o,R)??[],"the listResourceKeys port result"),A=await s(o,$,P,R);return Object.fromEntries($.map(G=>[G,Ke(G,Wt(A[G],R))]))}return{requirePermission:c,getMyPermissions:x}}export{pr as AuthzAdminAppView,cr as AuthzErrorBoundary,Rt as AuthzGrantsView,kt as AuthzGraphView,zt as AuthzGroupRolesView,ur as AuthzLayout,It as AuthzResourcesView,He as AuthzRolesView,X as AuthzUsageError,St as AuthzUserRolesView,de as ErrorAlert,N as Field,Ue as MyPermissionGroupStatus,Ae as MyPermissionIndicator,Xt as MyPermissionStatus,vr as createAuthz,qt as createAuthzAdminApp,Me as createAuthzAdminServer,nt as defaultAuthzAdminLabels,yr as defineResources,Re as flattenGroupItems,_e as formatResourceTooltip,yt as getPermissionSummary,wt as makeAuthzErrorBoundary,ge as resolveLabels,gr as resourceKeysOf,Ke as toPermissionView,i as ui,Ee as usePermission};
|
|
3
|
-
//# sourceMappingURL=index.mjs.map
|
|
1
|
+
import{data as ut,redirect as ct}from"react-router";import{AUTHZ_ACTIONS as De,AuthzDeniedError as he,assertTenantId as st,isSameTenant as We,RESERVED_ROLE_ANONYMOUS as it,RESERVED_ROLE_AUTHENTICATED as at}from"@aiquants/authz-core";import{data as U,redirect as dt}from"react-router";var ot={title:"Authorization (RBAC)",myPermission:"Your permissions",tabs:{roles:"Roles",resources:"Resources",role_permissions:"Permissions",user_roles:"User assignments",group_roles:"Group assignments",graph:"Graph"},common:{add:"Add",save:"Save",delete:"Delete",remove:"Remove",assign:"Assign",grant:"Grant",select:"Select\u2026",active:"\u25CB Enabled",inactive:"\xD7 Disabled",optional:"optional",tenant:"tenant",tenantHint:"must match the tenant you are signed in to",unknownTenant:"\u2014"},roles:{heading:"Roles (TMRole)",note:"Edit name / description inline and click Save (role_key is an immutable identifier).",roleKey:"role_key",name:"name",description:"description",activeHeader:"Active",empty:"No roles",newHeading:"New role",hintRoleKey:"e.g. admin"},resources:{heading:"Resources (TMResource)",note:"Edit name / description inline and click Save (app_key / resource_key are immutable identifiers).",appKey:"app_key",resourceKey:"resource_key",name:"name",description:"description",empty:"No resources",newHeading:"New resource",hintAppKey:"e.g. quants",hintResourceKey:"e.g. daily_report",hintDailyReport:"optional"},grants:{heading:"Permissions (TDRolePermission)",note:"Empty row_scope / column_scope = all rows / all columns (NULL). JSON must satisfy the row_scope / column_scope contract.",role:"role",resource:"resource",action:"action",rowScope:"row_scope",columnScope:"column_scope",empty:"No permissions",newHeading:"Grant a permission",rowScopeHint:"JSON / empty = all rows",columnScopeHint:"JSON / empty = all columns",rowScopePlaceholder:"empty = all rows (NULL)",columnScopePlaceholder:"empty = all columns (NULL)",nullRows:"NULL (all rows)",nullCols:"NULL (all columns)",selectPlaceholder:"Select\u2026"},userRoles:{heading:"User assignments (TDUserRole)",note:"Assign active roles to specific users.",user:"user",role:"role",empty:"No assignments",newHeading:"Assign a role",selectPlaceholder:"Select\u2026"},groupRoles:{heading:"Group assignments (TDGroupRole)",note:"Assign active roles to user groups.",group:"group",role:"role",empty:"No group assignments",newHeading:"Assign a role to group",selectPlaceholder:"Select\u2026"},error:{forbiddenTitle:"Access denied",forbiddenBody:"You don't have permission to view this screen. Ask an administrator to grant access.",genericTitlePrefix:"Error",genericTitle:"An error occurred",genericBody:"An unexpected error occurred. Please try again later."},warn:{selfRoleDisable:"This role backs your own authorization-admin access. Disabling it may lock you out of this screen. Continue?",selfRoleDelete:"This role backs your own authorization-admin access. Deleting it may lock you out of this screen. Continue?",selfAssignmentRemove:"This assignment backs your own authorization-admin access. Removing it may lock you out of this screen. Continue?"}};function ge(t){let n=ot;return t?{title:t.title??n.title,myPermission:t.myPermission??n.myPermission,tabs:{...n.tabs,...t.tabs},common:{...n.common,...t.common},roles:{...n.roles,...t.roles},resources:{...n.resources,...t.resources},grants:{...n.grants,...t.grants},userRoles:{...n.userRoles,...t.userRoles},groupRoles:{...n.groupRoles,...t.groupRoles},error:{...n.error,...t.error},warn:{...n.warn,...t.warn}}:n}function Me(t){return t===at||t===it}var lt=t=>t instanceof Response;function le(t){if(lt(t))throw t;if(t instanceof he)throw new Response(t.message,{status:403});return U({error:t instanceof Error?t.message:"\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"},{status:400})}function Ne(t){let n=t.store,d=t.resourceKey??"authz_admin",s=ge(t.labels);function c(a,u){throw new he({appKey:"",resourceKey:d,action:u,reason:"tenant-mismatch",tenantId:a.tenantId,userId:a.userId})}function p(a,u,S,f){let v=a.find(T=>T.id===u);return v||c(S,f),v}function x(a,u,S,f){let v=p(a,u,S,f);return We(S.tenantId,v.tenantId)||c(S,f),v}function o(a,u,S){We(a.tenantId,S)||c(a,u)}async function I(a,u,S){return x(await n.listRoles(a.tenantId),S,a,u)}async function K(a,u,S){return x(await n.listResources(a.tenantId),S,a,u)}async function P(a,u,S){return x(await n.listGroups(a.tenantId),S,a,u)}async function R(a,u,S){p(await n.listUsers(a.tenantId),S,a,u)}async function $(a,u,S){p(await n.listGrants(a.tenantId),S,a,u)}let A=async(a,u)=>{let{userId:S,tenantId:f,permission:v}=await t.requirePermission(a,u);if(st(f,"createAuthzAdminServer(requirePermission.tenantId)"),S==null)throw new he({appKey:"",resourceKey:u.resourceKey,action:u.action,reason:"unresolved-user",tenantId:f,userId:null});return{userId:S,tenantId:f,permission:v}};async function G(a){await t.requireUser(a);try{let{userId:u,tenantId:S,permission:f}=await A(a,{resourceKey:d,action:"read"});return{userId:u,tenantId:S,myPermissions:{[d]:f}}}catch(u){throw u instanceof he?new Response(`Forbidden: ${d}`,{status:403}):u}}let g=async a=>{let[u,S]=await Promise.all([n.listRoles(a.tenantId),n.getSelfAdminContext(a.tenantId,Number(a.userId))]);return{roles:u,selfAdminRoleIds:S.selfAdminRoleIds,tenantId:a.tenantId,labels:s}},z=async a=>({resources:await n.listResources(a.tenantId),tenantId:a.tenantId,labels:s}),M=async a=>{let[u,S,f]=await Promise.all([n.listGrants(a.tenantId),n.listRoles(a.tenantId),n.listResources(a.tenantId)]);return{grants:u,roles:S,resources:f,tenantId:a.tenantId,labels:s}},O=async a=>{let[u,S,f,v]=await Promise.all([n.listUserRoles(a.tenantId),n.listRoles(a.tenantId),n.listUsers(a.tenantId),n.getSelfAdminContext(a.tenantId,Number(a.userId))]);return{assignments:u,roles:S,users:f,actorUserId:v.actorUserId,selfAdminRoleIds:v.selfAdminRoleIds,tenantId:a.tenantId,labels:s}},re=async a=>{let[u,S,f]=await Promise.all([n.listGroupRoles(a.tenantId),n.listRoles(a.tenantId),n.listGroups(a.tenantId)]);return{groupRoles:u,roles:S,groups:f,tenantId:a.tenantId,labels:s}},ae=async a=>{let[u,S,f,v,T,L,N]=await Promise.all([n.listUsers(a.tenantId),n.listRoles(a.tenantId),n.listResources(a.tenantId),n.listGrants(a.tenantId),n.listUserRoles(a.tenantId),n.listGroupRoles(a.tenantId),n.listGroups(a.tenantId)]);return{users:u,roles:S,resources:f,grants:v,assignments:T,groupRoles:L,groups:N,tenantId:a.tenantId,labels:s}};return{labels:s,resourceKey:d,layoutGuard:G,layout:{async loader({request:a}){let{tenantId:u,myPermissions:S}=await G(a);return{myPermissions:S,tenantId:u,labels:s,adminResourceKey:d}}},index:{loader(){throw dt("/authz/roles")}},roles:{data:g,async loader({request:a}){let u=await A(a,{resourceKey:d,action:"read"});return g(u)},async action({request:a}){let u=await a.formData(),S=String(u.get("_action"));try{switch(S){case"create":{let f=await A(a,{resourceKey:d,action:"create"}),v=String(u.get("tenantId")??"").trim(),T=String(u.get("roleKey")??"").trim(),L=String(u.get("name")??"").trim();return v&&T&&L?(o(f,"create",v),await n.createRole(f.tenantId,{tenantId:v,roleKey:T,name:L,description:String(u.get("description")??"").trim()||null},String(f.userId)),{ok:!0}):U({error:"tenant_id \u3068 role_key \u3068 name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"save":{let f=await A(a,{resourceKey:d,action:"update"}),v=String(u.get("tenantId")??"").trim(),T=String(u.get("roleKey")??"").trim(),L=String(u.get("name")??"").trim();if(!(v&&T&&L))return U({error:"tenantId \u3068 roleKey \u3068 name \u306F\u5FC5\u9808\u3067\u3059"},{status:400});o(f,"update",v);let N=await I(f,"update",Number(u.get("id")));return(Me(N.roleKey)||Me(T))&&N.roleKey!==T?U({error:"\u4E88\u7D04\u30ED\u30FC\u30EB\u306E role_key \u306F\u5909\u66F4\u3067\u304D\u307E\u305B\u3093"},{status:400}):(await n.updateRole(f.tenantId,N.id,{tenantId:v,roleKey:T,name:L,description:String(u.get("description")??"").trim()||null},String(f.userId)),{ok:!0})}case"toggle":{let f=await A(a,{resourceKey:d,action:"update"}),v=await I(f,"update",Number(u.get("id")));return await n.setRoleActive(f.tenantId,v.id,u.get("isActive")==="true",String(f.userId)),{ok:!0}}case"delete":{let f=await A(a,{resourceKey:d,action:"delete"}),v=await I(f,"delete",Number(u.get("id")));return await n.deleteRole(f.tenantId,v.id),{ok:!0}}default:return U({error:"unknown action"},{status:400})}}catch(f){return le(f)}}},resources:{data:z,async loader({request:a}){let u=await A(a,{resourceKey:d,action:"read"});return z(u)},async action({request:a}){let u=await a.formData(),S=String(u.get("_action"));try{switch(S){case"create":{let f=await A(a,{resourceKey:d,action:"create"}),v=String(u.get("tenantId")??"").trim(),T=String(u.get("appKey")??"").trim(),L=String(u.get("resourceKey")??"").trim(),N=String(u.get("name")??"").trim();return v&&T&&L&&N?(o(f,"create",v),await n.createResource(f.tenantId,{tenantId:v,appKey:T,resourceKey:L,name:N,description:String(u.get("description")??"").trim()||null},String(f.userId)),{ok:!0}):U({error:"tenant_id / app_key / resource_key / name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"save":{let f=await A(a,{resourceKey:d,action:"update"}),v=String(u.get("name")??"").trim();if(!v)return U({error:"name \u306F\u5FC5\u9808\u3067\u3059"},{status:400});let T=await K(f,"update",Number(u.get("id")));return await n.updateResource(f.tenantId,T.id,{name:v,description:String(u.get("description")??"").trim()||null},String(f.userId)),{ok:!0}}case"delete":{let f=await A(a,{resourceKey:d,action:"delete"}),v=await K(f,"delete",Number(u.get("id")));return await n.deleteResource(f.tenantId,v.id),{ok:!0}}default:return U({error:"unknown action"},{status:400})}}catch(f){return le(f)}}},grants:{data:M,async loader({request:a}){let u=await A(a,{resourceKey:d,action:"read"});return M(u)},async action({request:a}){let u=await a.formData(),S=String(u.get("_action"));try{switch(S){case"create":{let f=await A(a,{resourceKey:d,action:"create"}),v=String(u.get("tenantId")??"").trim(),T=Number(u.get("roleId")),L=Number(u.get("resourceId"));if(!(v&&T&&L))return U({error:"tenant_id \u3068\u30ED\u30FC\u30EB\u3068\u30EA\u30BD\u30FC\u30B9\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044"},{status:400});let N=String(u.get("action")??"");if(!De.includes(N))return U({error:"\u7121\u52B9\u306A action \u3067\u3059"},{status:400});let Z=N;o(f,"create",v);let Q=await I(f,"create",T),y=await K(f,"create",L);return await n.createGrant(f.tenantId,{tenantId:v,roleId:Q.id,resourceId:y.id,action:Z,rowScope:String(u.get("rowScope")??""),columnScope:String(u.get("columnScope")??"")},String(f.userId)),{ok:!0}}case"save":{let f=await A(a,{resourceKey:d,action:"update"}),v=String(u.get("action")??"");if(!De.includes(v))return U({error:"\u7121\u52B9\u306A action \u3067\u3059"},{status:400});let T=v,L=Number(u.get("id"));return await $(f,"update",L),await n.updateGrant(f.tenantId,L,{action:T,rowScope:String(u.get("rowScope")??""),columnScope:String(u.get("columnScope")??"")},String(f.userId)),{ok:!0}}case"delete":{let f=await A(a,{resourceKey:d,action:"delete"}),v=Number(u.get("id"));return await $(f,"delete",v),await n.deleteGrant(f.tenantId,v),{ok:!0}}default:return U({error:"unknown action"},{status:400})}}catch(f){return le(f)}}},userRoles:{data:O,async loader({request:a}){let u=await A(a,{resourceKey:d,action:"read"});return O(u)},async action({request:a}){let u=await a.formData(),S=String(u.get("_action"));try{switch(S){case"assign":{let f=await A(a,{resourceKey:d,action:"create"}),v=Number(u.get("userId")),T=Number(u.get("roleId"));if(!(v&&T))return U({error:"\u30E6\u30FC\u30B6\u30FC\u3068\u30ED\u30FC\u30EB\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044"},{status:400});await R(f,"create",v);let L=await I(f,"create",T);return await n.assignUserRole(f.tenantId,v,L.id,String(f.userId)),{ok:!0}}case"remove":{let f=await A(a,{resourceKey:d,action:"delete"}),v=Number(u.get("userId"));await R(f,"delete",v);let T=await I(f,"delete",Number(u.get("roleId")));return await n.removeUserRole(f.tenantId,v,T.id),{ok:!0}}default:return U({error:"unknown action"},{status:400})}}catch(f){return le(f)}}},groupRoles:{data:re,async loader({request:a}){let u=await A(a,{resourceKey:d,action:"read"});return re(u)},async action({request:a}){let u=await a.formData(),S=String(u.get("_action"));try{switch(S){case"assign":{let f=await A(a,{resourceKey:d,action:"create"}),v=Number(u.get("groupId")),T=Number(u.get("roleId"));if(!(v&&T))return U({error:"\u30B0\u30EB\u30FC\u30D7\u3068\u30ED\u30FC\u30EB\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044"},{status:400});let L=await P(f,"create",v),N=await I(f,"create",T);return await n.assignGroupRole(f.tenantId,L.id,N.id,String(f.userId)),{ok:!0}}case"remove":{let f=await A(a,{resourceKey:d,action:"delete"}),v=await P(f,"delete",Number(u.get("groupId"))),T=await I(f,"delete",Number(u.get("roleId")));return await n.removeGroupRole(f.tenantId,v.id,T.id),{ok:!0}}default:return U({error:"unknown action"},{status:400})}}catch(f){return le(f)}}},graph:{data:ae,async loader({request:a}){let u=await A(a,{resourceKey:d,action:"read"});return ae(u)}}}}function Ee(t){return String(t["*"]??"").split("/")[0]}function Bt(t){let n=Ne(t),d=t.basePath??"/authz",s=["roles","resources","role_permissions","user_roles","group_roles","graph"],c={roles:n.roles.data,resources:n.resources.data,role_permissions:n.grants.data,user_roles:n.userRoles.data,group_roles:n.groupRoles.data,graph:n.graph.data},p=new Map([["roles",n.roles.action],["resources",n.resources.action],["role_permissions",n.grants.action],["user_roles",n.userRoles.action],["group_roles",n.groupRoles.action]]);async function x(I){let K=Ee(I.params);if(!s.includes(K))throw ct(`${d}/roles`);let{userId:P,tenantId:R,myPermissions:$}=await n.layoutGuard(I.request),A=await c[K]({tenantId:R,userId:P});return{segment:K,basePath:d,myPermissions:$,adminResourceKey:n.resourceKey,...A}}async function o(I){let K=Ee(I.params),P=p.get(K);return P?P(I):ut({error:"unknown action"},{status:400})}return{loader:x,action:o,server:n}}import{jsx as pt,jsxs as Ae}from"react/jsx-runtime";var i={page:{padding:"1.25rem",maxWidth:1280,margin:"0 auto",color:"#0f172a"},tableContainer:{width:"100%",overflowX:"auto",marginBottom:"1rem",WebkitOverflowScrolling:"touch"},table:{borderCollapse:"collapse",width:"100%",fontSize:"0.9rem",tableLayout:"fixed"},th:{textAlign:"left",borderBottom:"2px solid #e2e8f0",padding:"0.45rem 0.65rem",fontSize:"0.78rem",color:"#475569",fontWeight:600,textTransform:"uppercase",letterSpacing:"0.03em"},td:{borderBottom:"1px solid #f1f5f9",padding:"0.5rem 0.65rem",verticalAlign:"middle",wordBreak:"break-all"},input:{padding:"0.4rem 0.55rem",border:"1px solid #cbd5e1",borderRadius:6,fontSize:"0.9rem",background:"#fff",width:"100%",boxSizing:"border-box"},select:{padding:"0.4rem 0.55rem",border:"1px solid #cbd5e1",borderRadius:6,fontSize:"0.9rem",background:"#fff",width:"100%",boxSizing:"border-box"},textarea:{padding:"0.4rem 0.55rem",border:"1px solid #cbd5e1",borderRadius:6,fontSize:"0.82rem",fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",minHeight:"3.25rem",resize:"vertical",width:"100%",boxSizing:"border-box"},button:{padding:"0.3rem 0.7rem",border:"1px solid #cbd5e1",borderRadius:6,background:"#fff",cursor:"pointer",fontSize:"0.82rem",color:"#334155"},save:{padding:"0.3rem 0.7rem",border:"1px solid #2563eb",borderRadius:6,background:"#eff6ff",cursor:"pointer",fontSize:"0.82rem",color:"#2563eb",fontWeight:600},danger:{padding:"0.3rem 0.7rem",border:"1px solid #fecaca",borderRadius:6,background:"#fff",cursor:"pointer",fontSize:"0.82rem",color:"#dc2626"},primary:{padding:"0.5rem 1.25rem",border:"1px solid #2563eb",borderRadius:6,background:"#2563eb",color:"#fff",cursor:"pointer",fontSize:"0.9rem",fontWeight:600,alignSelf:"flex-start"},card:{display:"flex",flexDirection:"column",gap:"0.85rem",maxWidth:600,marginTop:"0.75rem",padding:"1rem 1.1rem",border:"1px solid #e2e8f0",borderRadius:10,background:"#f8fafc"},code:{fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",fontSize:"0.78rem",color:"#334155",wordBreak:"break-all"},muted:{color:"#94a3b8"},h2:{fontSize:"1.05rem",margin:"0 0 0.35rem",fontWeight:700},h3:{fontSize:"0.92rem",margin:"1.25rem 0 0",color:"#334155",fontWeight:600},note:{color:"#64748b",fontSize:"0.82rem",margin:"0 0 0.75rem"},empty:{color:"#94a3b8",padding:"0.75rem 0.65rem"}};function E({label:t,hint:n,children:d}){return Ae("div",{style:{display:"flex",flexDirection:"column",gap:"0.3rem"},children:[Ae("span",{style:{fontSize:"0.8rem",color:"#475569",fontWeight:600},children:[t,n?Ae("span",{style:{fontWeight:400,color:"#94a3b8"},children:[" \u2014 ",n]}):null]}),d]})}function de({message:t}){return t?pt("p",{role:"alert",style:{color:"#dc2626",background:"#fef2f2",border:"1px solid #fecaca",borderRadius:8,padding:"0.55rem 0.8rem",fontSize:"0.85rem",margin:"0.25rem 0"},children:t}):null}import{AUTHZ_ACTIONS as qe}from"@aiquants/authz-core";import{SelectBox as ne}from"@aiquants/select-box";import{useState as B}from"react";import{Form as V,isRouteErrorResponse as vt,NavLink as wt,Outlet as It,useActionData as ce,useLoaderData as oe,useRouteError as At}from"react-router";import{useEffect as yt,useRef as gt,useState as ht}from"react";function _e(t){let n=t?.canRead?t.readPartial?"partial":"full":"none",d=t?.canCreate&&t?.canUpdate?"full":t?.canCreate||t?.canUpdate?"partial":"none",s=t?.canDelete?"full":"none";return{canRead:!!t?.canRead,canCreate:!!t?.canCreate,canUpdate:!!t?.canUpdate,canDelete:!!t?.canDelete,canWrite:!!t?.canWrite,readState:n,writeState:d,deleteState:s}}import{jsx as J,jsxs as ue}from"react/jsx-runtime";var mt={full:{bg:"#ecfdf5",text:"#047857",border:"#a7f3d0"},partial:{bg:"#fffbeb",text:"#b45309",border:"#fde68a"},none:{bg:"#f8fafc",text:"#94a3b8",border:"#cbd5e1"}};function Oe(t,n){let d=t?.trim(),s=n?.trim();if(s&&d&&s!==d)return`\u5BFE\u8C61\u30EA\u30BD\u30FC\u30B9: ${s} (${d})`;if(s||d)return`\u5BFE\u8C61\u30EA\u30BD\u30FC\u30B9: ${s||d}`}function ft({state:t}){return t==="full"?J("svg",{style:{width:"0.85rem",height:"0.85rem",flexShrink:0},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:3,"aria-hidden":"true",children:J("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 13l4 4L19 7"})}):t==="partial"?J("svg",{style:{width:"0.85rem",height:"0.85rem",flexShrink:0},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2.5,"aria-hidden":"true",children:J("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}):J("svg",{style:{width:"0.85rem",height:"0.85rem",flexShrink:0},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2.5,"aria-hidden":"true",children:J("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"})})}function Re({permission:t,resourceName:n,expectedResourceKey:d,showResourceTooltip:s=!0,labels:c,showScopeSummary:p=!0,className:x="authz-permission-indicator"}){let o=_e(t),I={read:c?.read??"\u95B2\u89A7",write:c?.write??"\u7DE8\u96C6",delete:c?.delete??"\u524A\u9664"},K=t?.resourceKey,P=n||K,R=s?Oe(K,n):void 0,$=!!(d&&K&&K!==d);$&&typeof console<"u"&&typeof console.error=="function"&&console.error(`[Authz Warning] Resource key mismatch in MyPermissionIndicator! Expected: "${d}", but received permission for: "${K}".`);let A=(G,g,z)=>{let M=mt[g],O=R?`${z}: ${g}
|
|
2
|
+
${R}`:`${z}: ${g}`;return ue("span",{"data-perm":G,"data-state":g,title:O,style:{display:"inline-flex",alignItems:"center",gap:"0.25rem",padding:"0.2rem 0.5rem",borderRadius:"100px",fontSize:"0.75rem",fontWeight:600,backgroundColor:M.bg,color:M.text,border:`1px solid ${M.border}`,lineHeight:1,userSelect:"none"},children:[J(ft,{state:g}),J("span",{children:z})]})};return ue("span",{className:x,title:R,"data-resource":K??"","data-resource-name":P??"","data-mismatch":$?"true":void 0,style:{display:"inline-flex",gap:"0.35rem",alignItems:"center",verticalAlign:"middle"},children:[A("read",o.readState,I.read),A("write",o.writeState,I.write),A("delete",o.deleteState,I.delete),p&&o.readState==="partial"?J("span",{"data-perm":"scope",title:R,style:{fontSize:"0.7rem",color:"#b45309",backgroundColor:"#fef3c7",padding:"0.15rem 0.35rem",borderRadius:"4px",fontWeight:600},children:"\u90E8\u5206\u5236\u9650"}):null,$?ue("span",{"data-testid":"resource-mismatch-warning",title:`expected: "${d}", actual: "${K}"`,style:{fontSize:"0.7rem",color:"#991b1b",backgroundColor:"#fee2e2",border:"1px solid #fca5a5",padding:"0.15rem 0.35rem",borderRadius:"4px",fontWeight:700},children:["\u26A0\uFE0F \u30EA\u30BD\u30FC\u30B9\u4E0D\u4E00\u81F4 (",K," \u2260 ",d,")"]}):null]})}function Zt({permission:t,resourceName:n,expectedResourceKey:d,prefixLabel:s="\u3042\u306A\u305F\u306E\u6A29\u9650",showPrefixLabel:c=!0,showResourceTooltip:p=!0,labels:x,showScopeSummary:o=!0,className:I="authz-permission-status",style:K}){let P=t?.resourceKey,R=n||P,$=p?Oe(P,n):void 0;return ue("span",{className:I,title:$,"data-testid":"my-permission-status","data-resource":P??"","data-resource-name":R??"",style:{fontSize:"0.82rem",color:"#475569",display:"inline-flex",alignItems:"center",gap:"0.4rem",...K},children:[c&&ue("span",{"data-testid":"prefix-label",children:[s,":"]}),J(Re,{permission:t,resourceName:n,expectedResourceKey:d,showResourceTooltip:p,labels:x,showScopeSummary:o})]})}import{jsx as te,jsxs as H}from"react/jsx-runtime";function Se(t,n=0){let d=[];for(let s of t){let c=s.level??n;d.push({...s,level:c}),s.children&&s.children.length>0&&d.push(...Se(s.children,c+1))}return d}var Ue={"2xs":{fontSize:"0.6rem",pillPadding:"0.05rem 0.25rem",pillGap:"0.15rem",wrapperGap:"0.15rem",triggerPadding:"0.1rem 0.35rem",triggerFontSize:"0.62rem",badgeFontSize:"0.58rem"},xs:{fontSize:"0.65rem",pillPadding:"0.08rem 0.35rem",pillGap:"0.18rem",wrapperGap:"0.2rem",triggerPadding:"0.12rem 0.4rem",triggerFontSize:"0.68rem",badgeFontSize:"0.62rem"},sm:{fontSize:"0.72rem",pillPadding:"0.1rem 0.4rem",pillGap:"0.2rem",wrapperGap:"0.25rem",triggerPadding:"0.15rem 0.45rem",triggerFontSize:"0.72rem",badgeFontSize:"0.65rem"},md:{fontSize:"0.78rem",pillPadding:"0.15rem 0.5rem",pillGap:"0.3rem",wrapperGap:"0.35rem",triggerPadding:"0.2rem 0.6rem",triggerFontSize:"0.78rem",badgeFontSize:"0.7rem"},lg:{fontSize:"0.85rem",pillPadding:"0.25rem 0.65rem",pillGap:"0.4rem",wrapperGap:"0.45rem",triggerPadding:"0.25rem 0.75rem",triggerFontSize:"0.85rem",badgeFontSize:"0.75rem"}};function bt(t,n){let d=n?.noPermission??"\u6A29\u9650\u306A\u3057",s=n?.fullWrite??"\u7DE8\u96C6\u53EF",c=n?.partialRead??"\u4E00\u90E8\u95B2\u89A7",p=n?.readOnly??"\u95B2\u89A7\u306E\u307F";return t&&(t.canRead||t.canWrite||t.canDelete)?t.canWrite?{text:s,color:"#047857",bgColor:"#ecfdf5",borderColor:"#a7f3d0"}:t.canRead?t.readPartial?{text:c,color:"#b45309",bgColor:"#fffbeb",borderColor:"#fde68a"}:{text:p,color:"#1d4ed8",bgColor:"#eff6ff",borderColor:"#bfdbfe"}:{text:d,color:"#64748b",bgColor:"#f1f5f9",borderColor:"#cbd5e1"}:{text:d,color:"#64748b",bgColor:"#f1f5f9",borderColor:"#cbd5e1"}}function xt({item:t,size:n="md",labels:d}){let s=bt(t.permission,d),c=t.permission?.resourceKey||t.resourceKey||t.expectedResourceKey,p=t.resourceName||c,x=!!(t.expectedResourceKey&&t.permission?.resourceKey&&t.permission.resourceKey!==t.expectedResourceKey),o=Ue[n],I=`\u5BFE\u8C61: ${p}${c?` (${c})`:""}${t.permission?` | ${d?.read??"\u95B2\u89A7"}:${t.permission.canRead?"\u25CB":"\xD7"} ${d?.write??"\u7DE8\u96C6"}:${t.permission.canWrite?"\u25CB":"\xD7"} ${d?.delete??"\u524A\u9664"}:${t.permission.canDelete?"\u25CB":"\xD7"}`:""}`;return H("span",{title:I,"data-testid":`permission-pill-${t.resourceName}`,"data-mismatch":x?"true":"false",style:{display:"inline-flex",alignItems:"center",gap:o.pillGap,fontSize:o.fontSize,padding:o.pillPadding,borderRadius:"9999px",backgroundColor:x?"#fee2e2":s.bgColor,color:x?"#991b1b":s.color,border:`1px solid ${x?"#fca5a5":s.borderColor}`,fontWeight:600,lineHeight:"1.2"},children:[H("span",{children:[p,":"]}),te("span",{children:s.text}),x&&te("span",{title:`expected "${t.expectedResourceKey}", actual "${t.permission?.resourceKey}"`,children:"\u26A0\uFE0F"})]})}function Fe({items:t,prefixLabel:n="\u3042\u306A\u305F\u306E\u6A29\u9650",variant:d="pills",size:s="md",labels:c,className:p="authz-permission-group-status",style:x}){let[o,I]=ht(!1),K=gt(null),P=Ue[s];if(yt(()=>{if(d!=="popover"||!o)return;function R(A){K.current&&!K.current.contains(A.target)&&I(!1)}function $(A){A.key==="Escape"&&I(!1)}return document.addEventListener("mousedown",R),document.addEventListener("keydown",$),()=>{document.removeEventListener("mousedown",R),document.removeEventListener("keydown",$)}},[d,o]),d==="popover"){let R=Se(t),$=R.filter(z=>z.permission?.canWrite).length,A=R.filter(z=>z.permission?.canRead).length,G=R.length,g=G===0||$===0&&A===0?c?.noPermission??"\u6A29\u9650\u306A\u3057":$===G?c?.fullWrite??"\u7DE8\u96C6\u53EF":$>0?c?.partialWrite??"\u4E00\u90E8\u7DE8\u96C6\u53EF":c?.readOnly??"\u95B2\u89A7\u306E\u307F";return H("span",{ref:K,className:p,"data-testid":"my-permission-group-popover",style:{position:"relative",display:"inline-block",...x},children:[H("button",{type:"button",onClick:()=>I(!o),"data-testid":"permission-popover-trigger",style:{display:"inline-flex",alignItems:"center",gap:P.wrapperGap,fontSize:P.triggerFontSize,padding:P.triggerPadding,borderRadius:"6px",backgroundColor:"#f8fafc",color:"#334155",border:"1px solid #cbd5e1",fontWeight:600,cursor:"pointer"},children:[H("span",{children:["\u{1F512} ",n]}),H("span",{style:{fontSize:P.badgeFontSize,color:"#64748b"},children:["(",g,")"]}),te("span",{style:{fontSize:"0.65rem",marginLeft:"0.1rem"},children:o?"\u25B2":"\u25BE"})]}),o&&H("div",{"data-testid":"permission-popover-card",style:{position:"absolute",top:"calc(100% + 6px)",right:0,zIndex:50,minWidth:"280px",whiteSpace:"nowrap",padding:"0.75rem 0.85rem",backgroundColor:"#ffffff",borderRadius:"8px",boxShadow:"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",border:"1px solid #e2e8f0",fontSize:"0.82rem"},children:[H("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"0.5rem",paddingBottom:"0.4rem",borderBottom:"1px solid #f1f5f9",fontWeight:700,color:"#1e293b",whiteSpace:"nowrap"},children:[H("span",{children:["\u{1F512} ",n]}),te("button",{type:"button",onClick:()=>I(!1),style:{border:"none",background:"none",cursor:"pointer",color:"#94a3b8",fontSize:"0.85rem",padding:"0 0.2rem"},children:"\u2715"})]}),te("div",{style:{display:"flex",flexDirection:"column",gap:"0.4rem"},children:Se(t).map(z=>{let M=z.level??0,O=M>0;return H("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:"1.25rem",whiteSpace:"nowrap",paddingLeft:O?`${M*.85}rem`:"0"},children:[H("div",{style:{display:"inline-flex",alignItems:"center",whiteSpace:"nowrap"},children:[O&&te("span",{"aria-hidden":"true",style:{display:"inline-block",width:"10px",height:"10px",borderLeft:"1.5px solid #cbd5e1",borderBottom:"1.5px solid #cbd5e1",borderBottomLeftRadius:"3px",marginRight:"6px",marginTop:"-4px",flexShrink:0}}),H("span",{style:{fontWeight:O?500:600,color:O?"#64748b":"#1e293b",fontSize:O?"0.78rem":"0.82rem",whiteSpace:"nowrap"},children:[z.resourceName,":"]})]}),te(Re,{permission:z.permission,resourceName:z.resourceName,expectedResourceKey:z.expectedResourceKey,labels:c})]},z.resourceName)})})]})]})}return H("span",{className:p,"data-testid":"my-permission-group-pills",style:{display:"inline-flex",alignItems:"center",flexWrap:"wrap",gap:P.pillGap,fontSize:P.fontSize,color:"#475569",...x},children:[n&&H("span",{style:{fontWeight:600,color:"#334155"},children:[n,":"]}),te("span",{style:{display:"inline-flex",alignItems:"center",flexWrap:"wrap",gap:P.pillGap},children:t.map(R=>te(xt,{item:R,size:s,labels:c},R.resourceName))})]})}import{Fragment as be,jsx as e,jsxs as l}from"react/jsx-runtime";var pe=t=>t?.error;function me({tenantId:t,testId:n}){return e("td",{style:i.td,children:e("span",{style:i.code,"data-testid":n,children:t})})}function ke(t,n,d){let s=t.find(c=>c.id===n);return s?s.tenantId:d.common.unknownTenant}function He({children:t,renderHeader:n}){let{myPermissions:d,labels:s,adminResourceKey:c,basePath:p,tenantId:x}=oe(),o=p??"/authz",[I,K]=B("pills"),P=[["roles",s.tabs.roles],["resources",s.tabs.resources],["role_permissions",s.tabs.role_permissions],["user_roles",s.tabs.user_roles],["group_roles",s.tabs.group_roles],["graph",s.tabs.graph]],R=Object.entries(d||{}).map(([G,g])=>({resourceKey:G,resourceName:g?.resourceKey||G,permission:g,expectedResourceKey:G})),$=R.length>0?R:[{resourceKey:c,resourceName:c,permission:d?.[c],expectedResourceKey:c}],A=l("div",{style:{display:"flex",alignItems:"center",gap:"0.4rem"},children:[l("span",{"data-testid":"authz-tenant-badge",style:{...i.code,border:"1px solid #cbd5e1",borderRadius:4,padding:"1px 6px",background:"#f8fafc"},children:[s.common.tenant,": ",x]}),e(Fe,{prefixLabel:s.myPermission,items:$,variant:I,size:"xs"}),l("div",{style:{display:"inline-flex",borderRadius:"4px",border:"1px solid #cbd5e1",padding:"1px",backgroundColor:"#f8fafc",fontSize:"0.7rem"},children:[e("button",{type:"button",onClick:()=>K("pills"),"data-testid":"switch-variant-pills",style:{padding:"1px 5px",borderRadius:"3px",border:"none",cursor:"pointer",fontSize:"0.7rem",lineHeight:"1.2",fontWeight:I==="pills"?600:400,backgroundColor:I==="pills"?"#ffffff":"transparent",color:I==="pills"?"#1e293b":"#64748b",boxShadow:I==="pills"?"0 1px 2px rgba(0,0,0,0.05)":"none"},children:"Pills"}),e("button",{type:"button",onClick:()=>K("popover"),"data-testid":"switch-variant-popover",style:{padding:"1px 5px",borderRadius:"3px",border:"none",cursor:"pointer",fontSize:"0.7rem",lineHeight:"1.2",fontWeight:I==="popover"?600:400,backgroundColor:I==="popover"?"#ffffff":"transparent",color:I==="popover"?"#1e293b":"#64748b",boxShadow:I==="popover"?"0 1px 2px rgba(0,0,0,0.05)":"none"},children:"Popover"})]})]});return l("div",{className:"authz-admin",style:i.page,children:[n?n({title:s.title,annotation:A}):l("header",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:"0.75rem",flexWrap:"wrap",margin:"0 0 0.4rem"},children:[e("h1",{style:{fontSize:"1.15rem",margin:0,fontWeight:700,color:"#1e293b"},children:s.title}),A]}),e("nav",{style:{display:"flex",gap:"0.25rem",borderBottom:"1px solid #e2e8f0",margin:"0.6rem 0 1rem"},children:P.map(([G,g])=>e(wt,{to:`${o}/${G}`,style:({isActive:z})=>({padding:"0.5rem 0.9rem",textDecoration:"none",color:z?"#2563eb":"#475569",borderBottom:z?"2px solid #2563eb":"2px solid transparent",marginBottom:-1,fontWeight:z?700:500,fontSize:"0.92rem"}),children:g},G))}),t]})}function mr({renderHeader:t}={}){return e(He,{renderHeader:t,children:e(It,{})})}function Rt(t){let n=ge(t).error;return function(){let s=At(),c=vt(s)?s:null,p=c?.status===403||typeof s=="object"&&s!==null&&s.status===403,x=p?n.forbiddenTitle:c?`${n.genericTitlePrefix} (${c.status})`:n.genericTitle,o=p?n.forbiddenBody:c?typeof c.data=="string"&&c.data?c.data:c.statusText:n.genericBody;return e("div",{style:i.page,children:l("div",{role:"alert",style:{maxWidth:480,margin:"3rem auto",padding:"1.5rem",border:"1px solid #fecaca",borderRadius:12,background:"#fef2f2"},children:[e("h1",{style:{fontSize:"1.1rem",fontWeight:700,color:"#b91c1c",margin:"0 0 0.5rem"},children:x}),e("p",{style:{color:"#7f1d1d",fontSize:"0.9rem",margin:0,lineHeight:1.7},children:o})]})})}}var fr=Rt(),ze=(t,n)=>d=>{t&&!window.confirm(n)&&d.preventDefault()};function Ve(){let{roles:t,selfAdminRoleIds:n,labels:d,tenantId:s}=oe(),c=d.roles,p=d.common,x=new Set(n??[]);return l("section",{children:[e("h2",{style:i.h2,children:c.heading}),e(de,{message:pe(ce())}),e("p",{style:i.note,children:c.note}),e("div",{style:i.tableContainer,children:l("table",{style:i.table,children:[e("thead",{children:l("tr",{children:[e("th",{style:{...i.th,width:"12%"},children:p.tenant}),e("th",{style:{...i.th,width:"18%"},children:c.roleKey}),e("th",{style:{...i.th,width:"22%"},children:c.name}),e("th",{style:{...i.th,width:"28%"},children:c.description}),e("th",{style:{...i.th,width:"10%"},children:c.activeHeader}),e("th",{style:{...i.th,width:"10%"}})]})}),l("tbody",{children:[t.map(o=>l("tr",{children:[e(me,{tenantId:o.tenantId,testId:`tenant-role-${o.id}`}),l("td",{style:i.td,children:[e("input",{type:"hidden",name:"tenantId",value:o.tenantId,form:`save-role-${o.id}`}),o.roleKey==="@authenticated"||o.roleKey==="@anonymous"?l(be,{children:[e("input",{type:"hidden",name:"roleKey",value:o.roleKey,form:`save-role-${o.id}`}),e("span",{style:i.code,children:o.roleKey})]}):e("input",{name:"roleKey",defaultValue:o.roleKey,form:`save-role-${o.id}`,"aria-label":`roleKey-${o.id}`,required:!0,style:i.input})]}),e("td",{style:i.td,children:e("input",{name:"name",defaultValue:o.name,form:`save-role-${o.id}`,"aria-label":`name-${o.id}`,required:!0,style:i.input})}),e("td",{style:i.td,children:e("input",{name:"description",defaultValue:o.description??"",form:`save-role-${o.id}`,"aria-label":`description-${o.id}`,style:i.input})}),e("td",{style:i.td,children:l(V,{method:"post",style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"toggle"}),e("input",{type:"hidden",name:"id",value:o.id}),e("input",{type:"hidden",name:"isActive",value:String(!o.isActive)}),e("button",{type:"submit",style:i.button,onClick:o.isActive?ze(x.has(o.id),d.warn.selfRoleDisable):void 0,children:o.isActive?p.active:p.inactive})]})}),l("td",{style:{...i.td,whiteSpace:"nowrap"},children:[l(V,{method:"post",id:`save-role-${o.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:o.id}),e("button",{type:"submit",style:i.save,children:p.save})]}),l(V,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:o.id}),e("button",{type:"submit",style:i.danger,onClick:ze(x.has(o.id),d.warn.selfRoleDelete),children:p.delete})]})]})]},o.id)),t.length===0?e("tr",{children:e("td",{style:i.empty,colSpan:6,children:c.empty})}):null]})]})}),e("h3",{style:i.h3,children:c.newHeading}),l(V,{method:"post",style:i.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e(E,{label:p.tenant,hint:p.tenantHint,children:e("input",{name:"tenantId","aria-label":"tenant_id",defaultValue:s,required:!0,style:i.input})}),e(E,{label:c.roleKey,hint:c.hintRoleKey,children:e("input",{name:"roleKey","aria-label":"role_key",required:!0,style:i.input})}),e(E,{label:c.name,children:e("input",{name:"name","aria-label":"name",required:!0,style:i.input})}),e(E,{label:c.description,hint:p.optional,children:e("input",{name:"description","aria-label":"description",style:i.input})}),e("button",{type:"submit",style:i.primary,children:p.add})]})]})}function St(){let{resources:t,labels:n,tenantId:d}=oe(),s=n.resources,c=n.common;return l("section",{children:[e("h2",{style:i.h2,children:s.heading}),e(de,{message:pe(ce())}),e("p",{style:i.note,children:s.note}),e("div",{style:i.tableContainer,children:l("table",{style:i.table,children:[e("thead",{children:l("tr",{children:[e("th",{style:{...i.th,width:"12%"},children:c.tenant}),e("th",{style:{...i.th,width:"13%"},children:s.appKey}),e("th",{style:{...i.th,width:"18%"},children:s.resourceKey}),e("th",{style:{...i.th,width:"22%"},children:s.name}),e("th",{style:{...i.th,width:"25%"},children:s.description}),e("th",{style:{...i.th,width:"10%"}})]})}),l("tbody",{children:[t.map(p=>l("tr",{children:[e(me,{tenantId:p.tenantId,testId:`tenant-resource-${p.id}`}),e("td",{style:i.td,children:e("span",{style:i.code,children:p.appKey})}),e("td",{style:i.td,children:e("span",{style:i.code,children:p.resourceKey})}),e("td",{style:i.td,children:e("input",{name:"name",defaultValue:p.name,form:`save-res-${p.id}`,"aria-label":`name-${p.id}`,required:!0,style:i.input})}),e("td",{style:i.td,children:e("input",{name:"description",defaultValue:p.description??"",form:`save-res-${p.id}`,"aria-label":`description-${p.id}`,style:i.input})}),l("td",{style:{...i.td,whiteSpace:"nowrap"},children:[l(V,{method:"post",id:`save-res-${p.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:p.id}),e("button",{type:"submit",style:i.save,children:c.save})]}),l(V,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:p.id}),e("button",{type:"submit",style:i.danger,children:c.delete})]})]})]},p.id)),t.length===0?e("tr",{children:e("td",{style:i.empty,colSpan:6,children:s.empty})}):null]})]})}),e("h3",{style:i.h3,children:s.newHeading}),l(V,{method:"post",style:i.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e(E,{label:c.tenant,hint:c.tenantHint,children:e("input",{name:"tenantId","aria-label":"tenant_id",defaultValue:d,required:!0,style:i.input})}),e(E,{label:s.appKey,hint:s.hintAppKey,children:e("input",{name:"appKey","aria-label":"app_key",required:!0,style:i.input})}),e(E,{label:s.resourceKey,hint:s.hintResourceKey,children:e("input",{name:"resourceKey","aria-label":"resource_key",required:!0,style:i.input})}),e(E,{label:s.name,children:e("input",{name:"name","aria-label":"name",required:!0,style:i.input})}),e(E,{label:s.description,hint:c.optional,children:e("input",{name:"description","aria-label":"description",style:i.input})}),e("button",{type:"submit",style:i.primary,children:c.add})]})]})}function zt({g:t,tenantId:n,labels:d}){let s=d.common,[c,p]=B({label:t.action,value:t.action});return l("tr",{children:[e(me,{tenantId:n,testId:`tenant-grant-${t.id}`}),e("td",{style:i.td,children:e("span",{style:i.code,children:t.roleKey})}),e("td",{style:i.td,children:l("span",{style:i.code,children:[t.appKey,":",t.resourceKey]})}),e("td",{style:i.td,children:t.roleKey==="@anonymous"?e("span",{style:i.code,children:t.action}):l(be,{children:[e("input",{type:"hidden",name:"action",value:c.value,form:`save-grant-${t.id}`}),e(ne,{options:qe.map(x=>({label:x,value:x})),value:c,onChange:x=>{x&&p(x)}})]})}),e("td",{style:i.td,children:e("textarea",{name:"rowScope",defaultValue:t.rowScope??"",form:`save-grant-${t.id}`,"aria-label":`row_scope-${t.id}`,rows:2,placeholder:d.grants.rowScopePlaceholder,style:i.textarea})}),e("td",{style:i.td,children:e("textarea",{name:"columnScope",defaultValue:t.columnScope??"",form:`save-grant-${t.id}`,"aria-label":`column_scope-${t.id}`,rows:2,placeholder:d.grants.columnScopePlaceholder,style:i.textarea})}),l("td",{style:{...i.td,whiteSpace:"nowrap"},children:[l(V,{method:"post",id:`save-grant-${t.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:t.id}),e("button",{type:"submit",style:i.save,children:s.save})]}),l(V,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:t.id}),e("button",{type:"submit",style:i.danger,children:s.delete})]})]})]})}function Pt(){let{grants:t,roles:n,resources:d,labels:s,tenantId:c}=oe(),p=s.grants,x=s.common,o=n.map(z=>({label:z.roleKey,value:z.id})),I=d.map(z=>({label:`${z.appKey}:${z.resourceKey}`,value:z.id})),K=qe.map(z=>({label:z,value:z})),[P,R]=B(void 0),[$,A]=B(void 0),[G,g]=B({label:"read",value:"read"});return l("section",{children:[e("h2",{style:i.h2,children:p.heading}),e("p",{style:i.note,children:p.note}),e(de,{message:pe(ce())}),e("div",{style:i.tableContainer,children:l("table",{style:i.table,children:[e("thead",{children:l("tr",{children:[e("th",{style:{...i.th,width:"10%"},children:x.tenant}),e("th",{style:{...i.th,width:"13%"},children:p.role}),e("th",{style:{...i.th,width:"17%"},children:p.resource}),e("th",{style:{...i.th,width:"13%"},children:p.action}),e("th",{style:{...i.th,width:"19%"},children:p.rowScope}),e("th",{style:{...i.th,width:"18%"},children:p.columnScope}),e("th",{style:{...i.th,width:"10%"}})]})}),l("tbody",{children:[t.map(z=>e(zt,{g:z,tenantId:ke(n,z.roleId,s),labels:s},z.id)),t.length===0?e("tr",{children:e("td",{style:i.empty,colSpan:7,children:p.empty})}):null]})]})}),e("h3",{style:i.h3,children:p.newHeading}),l(V,{method:"post",style:i.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e("input",{type:"hidden",name:"roleId",value:P?.value??""}),e("input",{type:"hidden",name:"resourceId",value:$?.value??""}),e("input",{type:"hidden",name:"action",value:G?.value??""}),e(E,{label:x.tenant,hint:x.tenantHint,children:e("input",{name:"tenantId","aria-label":"tenant_id",defaultValue:c,required:!0,style:i.input})}),e(E,{label:p.role,children:e(ne,{options:o,value:P,onChange:z=>R(z||void 0),placeholder:p.selectPlaceholder})}),e(E,{label:p.resource,children:e(ne,{options:I,value:$,onChange:z=>A(z||void 0),placeholder:p.selectPlaceholder})}),e(E,{label:p.action,children:e(ne,{options:K,value:G,onChange:z=>g(z||void 0)})}),e(E,{label:p.rowScope,hint:p.rowScopeHint,children:e("textarea",{name:"rowScope","aria-label":"row_scope",rows:2,style:i.textarea,placeholder:'{"filters":[{"field":"\u90E8\u9580CD","op":"in","values":["A"]}]}'})}),e(E,{label:p.columnScope,hint:p.columnScopeHint,children:e("textarea",{name:"columnScope","aria-label":"column_scope",rows:2,style:i.textarea,placeholder:'{"mode":"deny","columns":["\u91D1\u984D"]}'})}),e("button",{type:"submit",style:i.primary,children:x.grant})]})]})}function kt(){let{assignments:t,roles:n,users:d,actorUserId:s,selfAdminRoleIds:c,labels:p}=oe(),x=p.userRoles,o=p.common,I=new Set(c??[]),K=d.map(g=>({label:`${g.email}\uFF08${g.displayName}\uFF09`,value:g.id})),P=n.filter(g=>g.roleKey!=="@authenticated"&&g.roleKey!=="@anonymous").map(g=>({label:g.roleKey,value:g.id})),[R,$]=B(void 0),[A,G]=B(void 0);return l("section",{children:[e("h2",{style:i.h2,children:x.heading}),e(de,{message:pe(ce())}),e("p",{style:i.note,children:x.note}),e("div",{style:i.tableContainer,children:l("table",{style:i.table,children:[e("thead",{children:l("tr",{children:[e("th",{style:{...i.th,width:"12%"},children:o.tenant}),e("th",{style:{...i.th,width:"40%"},children:x.user}),e("th",{style:{...i.th,width:"38%"},children:x.role}),e("th",{style:{...i.th,width:"10%"}})]})}),l("tbody",{children:[t.map(g=>l("tr",{children:[e(me,{tenantId:ke(n,g.roleId,p),testId:`tenant-assignment-${g.userId}-${g.roleId}`}),l("td",{style:i.td,children:[g.email,l("span",{style:i.muted,children:["\uFF08",g.displayName,"\uFF09"]})]}),e("td",{style:i.td,children:g.roleKey}),e("td",{style:i.td,children:l(V,{method:"post",style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"remove"}),e("input",{type:"hidden",name:"userId",value:g.userId}),e("input",{type:"hidden",name:"roleId",value:g.roleId}),e("button",{type:"submit",style:i.danger,onClick:ze(g.userId===s&&I.has(g.roleId),p.warn.selfAssignmentRemove),children:o.remove})]})})]},`${g.userId}-${g.roleId}`)),t.length===0?e("tr",{children:e("td",{style:i.empty,colSpan:4,children:x.empty})}):null]})]})}),e("h3",{style:i.h3,children:x.newHeading}),l(V,{method:"post",style:i.card,children:[e("input",{type:"hidden",name:"_action",value:"assign"}),e("input",{type:"hidden",name:"userId",value:R?.value??""}),e("input",{type:"hidden",name:"roleId",value:A?.value??""}),e(E,{label:x.user,children:e(ne,{options:K,value:R,onChange:g=>$(g||void 0),placeholder:x.selectPlaceholder})}),e(E,{label:x.role,children:e(ne,{options:P,value:A,onChange:g=>G(g||void 0),placeholder:x.selectPlaceholder})}),e("button",{type:"submit",style:i.primary,children:o.assign})]})]})}function Kt(){let{groupRoles:t,roles:n,groups:d,labels:s}=oe(),c=ce(),p=pe(c),x=s.groupRoles,o=s.common,I=n.filter(g=>g.isActive&&g.roleKey!=="@authenticated"&&g.roleKey!=="@anonymous"),K=d.map(g=>({label:`${g.name} (${g.groupKey})`,value:g.id})),P=I.map(g=>({label:`${g.name} (${g.roleKey})`,value:g.id})),[R,$]=B(K[0]),[A,G]=B(P[0]);return l("section",{style:{display:"flex",flexDirection:"column",gap:"1.25rem"},children:[l("div",{children:[e("h2",{style:i.h2,children:x.heading}),e("p",{style:i.note,children:x.note})]}),p&&e(de,{message:p}),l("table",{style:i.table,children:[e("thead",{children:l("tr",{children:[e("th",{style:{...i.th,width:"12%"},children:o.tenant}),e("th",{style:i.th,children:x.group}),e("th",{style:i.th,children:x.role}),e("th",{style:{...i.th,width:"100px"}})]})}),e("tbody",{children:t.length===0?e("tr",{children:e("td",{colSpan:4,style:{...i.td,textAlign:"center",color:"#64748b"},children:x.empty})}):t.map(g=>l("tr",{children:[e(me,{tenantId:ke(n,g.roleId,s),testId:`tenant-group-role-${g.groupId}-${g.roleId}`}),l("td",{style:i.td,children:[e("strong",{children:g.groupName})," ",l("span",{style:{color:"#64748b",fontSize:"0.85rem"},children:["(",g.groupKey,")"]})]}),e("td",{style:i.td,children:e("code",{children:g.roleKey})}),e("td",{style:{...i.td,textAlign:"right"},children:l(V,{method:"post",onSubmit:z=>!confirm("\u3053\u306E\u30B0\u30EB\u30FC\u30D7\u30ED\u30FC\u30EB\u5272\u5F53\u3092\u89E3\u9664\u3057\u307E\u3059\u304B\uFF1F")&&z.preventDefault(),children:[e("input",{type:"hidden",name:"_action",value:"remove"}),e("input",{type:"hidden",name:"groupId",value:g.groupId}),e("input",{type:"hidden",name:"roleId",value:g.roleId}),e("button",{type:"submit",style:i.danger,children:o.remove})]})})]},`${g.groupId}-${g.roleId}`))})]}),l(V,{method:"post",style:i.card,children:[e("h3",{style:i.h3,children:x.newHeading}),e("input",{type:"hidden",name:"_action",value:"assign"}),e("input",{type:"hidden",name:"groupId",value:R?.value??""}),e("input",{type:"hidden",name:"roleId",value:A?.value??""}),e(E,{label:x.group,children:e(ne,{options:K,value:R,onChange:g=>$(g||void 0),placeholder:x.selectPlaceholder})}),e(E,{label:x.role,children:e(ne,{options:P,value:A,onChange:g=>G(g||void 0),placeholder:x.selectPlaceholder})}),e("button",{type:"submit",style:i.primary,children:o.assign})]})]})}var Pe={read:{bg:"#ecfdf5",text:"#047857",border:"#a7f3d0"},create:{bg:"#eff6ff",text:"#1d4ed8",border:"#bfdbfe"},update:{bg:"#fffbeb",text:"#b45309",border:"#fde68a"},delete:{bg:"#fef2f2",text:"#b91c1c",border:"#fecaca"}};function Ct({users:t,roles:n,resources:d,grants:s,assignments:c,groupRoles:p=[],groups:x=[],selectedNode:o,onNodeClick:I}){let[K,P]=B(null),R=new Set(c.map(r=>r.userId)),$=new Set(p.map(r=>r.groupId)),A=new Set([...c.map(r=>r.roleId),...p.map(r=>r.roleId),...s.map(r=>r.roleId)]),G=new Set(s.map(r=>r.resourceId)),g=t.filter(r=>R.has(r.id)),z=x.filter(r=>$.has(r.id)),M=n.filter(r=>A.has(r.id)),O=d.filter(r=>G.has(r.id)),re=r=>{let h=s.filter(b=>b.resourceId===r),m=Array.from(new Set(h.map(b=>b.action)));return m.length>0?m:["none"]},ae=r=>32+re(r).length*24+6,a=16,u=0,S=new Map;O.forEach(r=>{let h=re(r.id),m=ae(r.id),b=u,W=new Map;h.forEach((F,q)=>{let _=b+8+24+q*24+12;W.set(F,_)}),S.set(r.id,{top:b,height:m,actionYMap:W}),u+=m+a});let f=u>0?u-a:0,v=52,T=18,L=v+T,N=M.length>0?M.length*L-T:0,Z=z.length>0?z.length*L-T:0,Q=g.length>0?g.length*L-T:0,k=Math.max(f,N,Z,Q,320)+60,C=(k-f)/2,j=(k-N)/2,D=(k-Z)/2,ee=(k-Q)/2,Y=(r,h)=>{let m=S.get(r);if(!m)return k/2;let b=m.actionYMap.get(h)??m.height/2;return C+b},fe=r=>j+r*L+v/2,Ce=r=>D+r*L+v/2,$e=r=>ee+r*L+v/2,ve=140,se=420,we=700,Ie=980,w=K||o,Xe=r=>{if(!w)return!0;if(w.type==="user")return w.id===r;if(w.type==="role")return c.some(h=>h.userId===r&&h.roleId===w.id);if(w.type==="group")return!1;if(w.type==="resource"){let h=s.filter(m=>m.resourceId===w.id).map(m=>m.roleId);return c.some(m=>m.userId===r&&h.includes(m.roleId))}return!0},Qe=r=>{if(!w)return!0;if(w.type==="group")return w.id===r;if(w.type==="role")return p.some(h=>h.groupId===r&&h.roleId===w.id);if(w.type==="user")return!1;if(w.type==="resource"){let h=s.filter(m=>m.resourceId===w.id).map(m=>m.roleId);return p.some(m=>m.groupId===r&&h.includes(m.roleId))}return!0},Je=r=>w?w.type==="role"?w.id===r:w.type==="user"?c.some(h=>h.userId===w.id&&h.roleId===r):w.type==="group"?p.some(h=>h.groupId===w.id&&h.roleId===r):w.type==="resource"?s.some(h=>h.resourceId===w.id&&h.roleId===r):!0:!0,Ze=r=>{if(!w)return!0;if(w.type==="resource")return w.id===r;if(w.type==="role")return s.some(h=>h.roleId===w.id&&h.resourceId===r);if(w.type==="group"){let h=p.filter(m=>m.groupId===w.id).map(m=>m.roleId);return s.some(m=>h.includes(m.roleId)&&m.resourceId===r)}if(w.type==="user"){let h=c.filter(m=>m.userId===w.id).map(m=>m.roleId);return s.some(m=>h.includes(m.roleId)&&m.resourceId===r)}return!0},et=(r,h)=>w?w.type==="user"?w.id===r&&c.some(m=>m.userId===r&&m.roleId===h):w.type==="role"?w.id===h&&c.some(m=>m.userId===r&&m.roleId===h):w.type==="resource"?s.filter(b=>b.resourceId===w.id).map(b=>b.roleId).includes(h)&&c.some(b=>b.userId===r&&b.roleId===h):w.type!=="group":!0,tt=(r,h)=>w?w.type==="group"?w.id===r&&p.some(m=>m.groupId===r&&m.roleId===h):w.type==="role"?w.id===h&&p.some(m=>m.groupId===r&&m.roleId===h):w.type==="resource"?s.filter(b=>b.resourceId===w.id).map(b=>b.roleId).includes(h)&&p.some(b=>b.groupId===r&&b.roleId===h):w.type!=="user":!0,rt=(r,h)=>w?w.type==="role"?w.id===r&&s.some(m=>m.roleId===r&&m.resourceId===h):w.type==="resource"?w.id===h&&s.some(m=>m.roleId===r&&m.resourceId===h):w.type==="group"?p.filter(b=>b.groupId===w.id).map(b=>b.roleId).includes(r)&&s.some(b=>b.roleId===r&&b.resourceId===h):w.type==="user"?c.filter(b=>b.userId===w.id).map(b=>b.roleId).includes(r)&&s.some(b=>b.roleId===r&&b.resourceId===h):!0:!0,Te=[];c.forEach(r=>{let h=g.findIndex(b=>b.id===r.userId),m=M.findIndex(b=>b.id===r.roleId);if(h!==-1&&m!==-1){let b=c.filter(_=>_.roleId===r.roleId),W=b.findIndex(_=>_.userId===r.userId&&_.roleId===r.roleId),F=b.length,q=F>1?Math.min(Math.max((W-(F-1)/2)*4,-16),16):0;Te.push({uIdx:h,rIdx:m,active:et(r.userId,r.roleId),key:`ur-${r.userId}-${r.roleId}`,offset:q})}});let Ge=[];p.forEach(r=>{let h=z.findIndex(b=>b.id===r.groupId),m=M.findIndex(b=>b.id===r.roleId);if(h!==-1&&m!==-1){let b=p.filter(_=>_.roleId===r.roleId),W=b.findIndex(_=>_.groupId===r.groupId&&_.roleId===r.roleId),F=b.length,q=F>1?Math.min(Math.max((W-(F-1)/2)*4,-16),16):0;Ge.push({gIdx:h,rIdx:m,active:tt(r.groupId,r.roleId),key:`gr-${r.groupId}-${r.roleId}`,offset:q})}});let Le=[];return s.forEach(r=>{let h=M.findIndex(b=>b.id===r.roleId),m=O.findIndex(b=>b.id===r.resourceId);if(h!==-1&&m!==-1){let b=s.filter(ye=>ye.resourceId===r.resourceId&&ye.action===r.action),W=b.findIndex(ye=>ye.id===r.id),F=b.length,q=F>1?Math.min(Math.max((W-(F-1)/2)*4,-12),12):0,_=Pe[r.action],nt=_?_.text:"#6366f1";Le.push({rIdx:h,resIdx:m,active:rt(r.roleId,r.resourceId),key:`rr-grant-${r.id}`,action:r.action,color:nt,offset:q})}}),e("div",{"data-testid":"authz-topology-map",style:{width:"100%",overflowX:"auto",backgroundColor:"#ffffff",borderRadius:"10px",border:"1px solid #e2e8f0",padding:"1rem",boxSizing:"border-box"},children:l("div",{style:{position:"relative",minWidth:"1160px",height:`${k}px`},children:[l("svg",{style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",pointerEvents:"none",zIndex:1},children:[e("title",{children:"Topology Connections"}),Le.map(r=>{let h=s.find(q=>`rr-grant-${q.id}`===r.key);if(!h)return null;let m=Y(h.resourceId,h.action)+r.offset,b=fe(r.rIdx),W=ve+135,F=se-135;return e("path",{d:`M ${ve+90} ${m} C ${W} ${m}, ${F} ${b}, ${se-90} ${b}`,fill:"none",stroke:r.active?r.color:"#cbd5e1",strokeWidth:r.active&&w?3:2,strokeOpacity:r.active?w?1:.75:.12,style:{transition:"all 0.2s ease"}},r.key)}),Ge.map(r=>{let h=fe(r.rIdx)+r.offset,m=Ce(r.gIdx),b=se+135,W=we-135;return e("path",{"data-testid":`topo-link-group-role-${r.key}`,"data-active":r.active?"true":"false",d:`M ${se+90} ${h} C ${b} ${h}, ${W} ${m}, ${we-90} ${m}`,fill:"none",stroke:r.active?"#8b5cf6":"#cbd5e1",strokeWidth:r.active&&w?3:2,strokeDasharray:"4 2",strokeOpacity:r.active?w?1:.75:.12,style:{transition:"all 0.2s ease"}},r.key)}),Te.map(r=>{let h=fe(r.rIdx)+r.offset,m=$e(r.uIdx),b=se+135,W=Ie-135;return e("path",{"data-testid":`topo-link-user-role-${r.key}`,"data-active":r.active?"true":"false",d:`M ${se+90} ${h} C ${b} ${h}, ${W} ${m}, ${Ie-90} ${m}`,fill:"none",stroke:r.active?"#4f46e5":"#cbd5e1",strokeWidth:r.active&&w?3:2,strokeOpacity:r.active?w?1:.75:.12,style:{transition:"all 0.2s ease"}},r.key)})]}),l("div",{style:{position:"relative",zIndex:2,width:"100%",height:"100%"},children:[O.map(r=>{let h=o?.type==="resource"&&o.id===r.id,m=Ze(r.id),b=S.get(r.id);if(!b)return null;let W=C+b.top,F=re(r.id);return l("div",{style:{position:"absolute",left:`${ve-90}px`,top:`${W}px`,width:"180px",height:`${b.height}px`,borderRadius:"8px",border:h?"2px solid #10b981":"1px solid #a7f3d0",backgroundColor:h?"#d1fae5":m?"#ffffff":"#f8fafc",opacity:m?1:.35,boxShadow:h?"0 4px 12px rgba(16, 185, 129, 0.2)":"0 1px 3px rgba(0,0,0,0.05)",transition:"all 0.15s ease",padding:"8px",boxSizing:"border-box",display:"flex",flexDirection:"column"},children:[l("button",{type:"button",onClick:()=>I("resource",r.id),onMouseEnter:()=>P({type:"resource",id:r.id}),onMouseLeave:()=>P(null),"data-testid":`topo-node-resource-${r.id}`,"aria-label":`\u30EA\u30BD\u30FC\u30B9: ${r.name}`,"aria-pressed":h,style:{background:"none",border:"none",padding:0,margin:0,cursor:"pointer",textAlign:"left",width:"100%",display:"flex",alignItems:"center",gap:"6px",marginBottom:"6px",height:"18px"},children:[e("span",{style:{fontSize:"1rem",flexShrink:0},children:"\u{1F511}"}),e("span",{style:{fontWeight:600,fontSize:"0.78rem",color:"#047857",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:r.name})]}),e("div",{style:{display:"flex",flexDirection:"column",gap:"2px"},children:F.map(q=>{if(q==="none")return e("div",{style:{fontSize:"0.68rem",color:"#94a3b8",height:"22px",display:"flex",alignItems:"center",padding:"0 6px"},children:"\u6A29\u9650\u8A2D\u5B9A\u306A\u3057"},"none");let _=Pe[q]??{bg:"#ecfdf5",text:"#047857",border:"#a7f3d0"};return l("div",{style:{height:"22px",boxSizing:"border-box",padding:"0 8px",borderRadius:"4px",backgroundColor:_.bg,color:_.text,border:`1px solid ${_.border}`,display:"flex",alignItems:"center",justifyContent:"space-between",fontSize:"0.68rem",fontWeight:600},children:[e("span",{children:q}),e("span",{style:{fontSize:"0.6rem",opacity:.6},children:"\u25CF"})]},q)})})]},r.id)}),M.map((r,h)=>{let m=o?.type==="role"&&o.id===r.id,b=Je(r.id),W=fe(h);return l("button",{type:"button",onClick:()=>I("role",r.id),onMouseEnter:()=>P({type:"role",id:r.id}),onMouseLeave:()=>P(null),"data-testid":`topo-node-role-${r.id}`,"aria-label":`\u30ED\u30FC\u30EB: ${r.name}`,"aria-pressed":m,style:{position:"absolute",left:`${se-90}px`,top:`${W-26}px`,width:"180px",height:"52px",borderRadius:"8px",border:m?"2px solid #6366f1":"1px solid #c7d2fe",backgroundColor:m?"#e0e7ff":b?"#ffffff":"#f8fafc",opacity:b?1:.35,cursor:"pointer",display:"flex",alignItems:"center",padding:"0 10px",gap:"8px",boxShadow:m?"0 4px 12px rgba(99, 102, 241, 0.2)":"0 1px 3px rgba(0,0,0,0.05)",transition:"all 0.15s ease",textAlign:"left",boxSizing:"border-box"},children:[e("span",{style:{fontSize:"1.1rem",flexShrink:0},children:"\u{1F6E1}\uFE0F"}),l("div",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flex:1,minWidth:0},children:[e("div",{style:{fontWeight:600,fontSize:"0.78rem",color:"#4338ca",textOverflow:"ellipsis",overflow:"hidden"},children:r.name}),e("div",{style:{fontSize:"0.68rem",color:"#64748b",fontFamily:"monospace",textOverflow:"ellipsis",overflow:"hidden"},children:r.roleKey})]})]},r.id)}),z.map((r,h)=>{let m=o?.type==="group"&&o.id===r.id,b=Qe(r.id),W=Ce(h);return l("button",{type:"button",onClick:()=>I("group",r.id),onMouseEnter:()=>P({type:"group",id:r.id}),onMouseLeave:()=>P(null),"data-testid":`topo-node-group-${r.id}`,"aria-label":`\u30B0\u30EB\u30FC\u30D7: ${r.name}`,"aria-pressed":m,style:{position:"absolute",left:`${we-90}px`,top:`${W-26}px`,width:"180px",height:"52px",borderRadius:"8px",border:m?"2px solid #8b5cf6":"1px solid #ddd6fe",backgroundColor:m?"#f3e8ff":b?"#ffffff":"#f8fafc",opacity:b?1:.35,cursor:"pointer",display:"flex",alignItems:"center",padding:"0 10px",gap:"8px",boxShadow:m?"0 4px 12px rgba(139, 92, 246, 0.2)":"0 1px 3px rgba(0,0,0,0.05)",transition:"all 0.15s ease",textAlign:"left",boxSizing:"border-box"},children:[e("span",{style:{fontSize:"1.1rem",flexShrink:0},children:"\u{1F465}"}),l("div",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flex:1,minWidth:0},children:[e("div",{style:{fontWeight:600,fontSize:"0.78rem",color:"#6d28d9",textOverflow:"ellipsis",overflow:"hidden"},children:r.name}),e("div",{style:{fontSize:"0.68rem",color:"#64748b",fontFamily:"monospace",textOverflow:"ellipsis",overflow:"hidden"},children:r.groupKey})]})]},r.id)}),g.map((r,h)=>{let m=o?.type==="user"&&o.id===r.id,b=Xe(r.id),W=$e(h);return l("button",{type:"button",onClick:()=>I("user",r.id),onMouseEnter:()=>P({type:"user",id:r.id}),onMouseLeave:()=>P(null),"data-testid":`topo-node-user-${r.id}`,"aria-label":`\u30E6\u30FC\u30B6\u30FC: ${r.displayName}`,"aria-pressed":m,style:{position:"absolute",left:`${Ie-90}px`,top:`${W-26}px`,width:"180px",height:"52px",borderRadius:"8px",border:m?"2px solid #0284c7":"1px solid #bae6fd",backgroundColor:m?"#e0f2fe":b?"#ffffff":"#f8fafc",opacity:b?1:.35,cursor:"pointer",display:"flex",alignItems:"center",padding:"0 10px",gap:"8px",boxShadow:m?"0 4px 12px rgba(2, 132, 199, 0.2)":"0 1px 3px rgba(0,0,0,0.05)",transition:"all 0.15s ease",textAlign:"left",boxSizing:"border-box"},children:[e("span",{style:{fontSize:"1.1rem",flexShrink:0},children:"\u{1F464}"}),l("div",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flex:1,minWidth:0},children:[e("div",{style:{fontWeight:600,fontSize:"0.78rem",color:"#0369a1",textOverflow:"ellipsis",overflow:"hidden"},children:r.displayName}),e("div",{style:{fontSize:"0.68rem",color:"#64748b",textOverflow:"ellipsis",overflow:"hidden"},children:r.email})]})]},r.id)})]})]})})}function $t(){let{users:t,roles:n,resources:d,grants:s,assignments:c,groupRoles:p=[],groups:x=[]}=oe(),[o,I]=B(null),[K,P]=B(""),[R,$]=B("topology"),A=new Map(n.map(y=>[y.id,y])),G=new Map(d.map(y=>[y.id,y])),g=new Map(x.map(y=>[y.id,y])),z=new Map(t.map(y=>[y.id,y])),M=y=>{if(!o)return!0;if(o.type==="user")return o.id===y;if(o.type==="role")return c.some(k=>k.userId===y&&k.roleId===o.id);if(o.type==="group")return!1;if(o.type==="resource"){let k=s.filter(C=>C.resourceId===o.id).map(C=>C.roleId);return c.some(C=>C.userId===y&&k.includes(C.roleId))}return!0},O=y=>{if(!o)return!0;if(o.type==="group")return o.id===y;if(o.type==="role")return p.some(k=>k.groupId===y&&k.roleId===o.id);if(o.type==="user")return!1;if(o.type==="resource"){let k=s.filter(C=>C.resourceId===o.id).map(C=>C.roleId);return p.some(C=>C.groupId===y&&k.includes(C.roleId))}return!0},re=y=>o?o.type==="role"?o.id===y:o.type==="user"?c.some(k=>k.userId===o.id&&k.roleId===y):o.type==="group"?p.some(k=>k.groupId===o.id&&k.roleId===y):o.type==="resource"?s.some(k=>k.resourceId===o.id&&k.roleId===y):!0:!0,ae=y=>{if(!o)return!0;if(o.type==="resource")return o.id===y;if(o.type==="role")return s.some(k=>k.roleId===o.id&&k.resourceId===y);if(o.type==="group"){let k=p.filter(C=>C.groupId===o.id).map(C=>C.roleId);return s.some(C=>k.includes(C.roleId)&&C.resourceId===y)}if(o.type==="user"){let k=c.filter(C=>C.userId===o.id).map(C=>C.roleId);return s.some(C=>k.includes(C.roleId)&&C.resourceId===y)}return!0},a=K.trim().toLowerCase(),u=t.filter(y=>!a||y.displayName.toLowerCase().includes(a)||y.email?.toLowerCase().includes(a)),S=x.filter(y=>!a||y.name.toLowerCase().includes(a)||y.groupKey.toLowerCase().includes(a)),f=n.filter(y=>!a||y.name.toLowerCase().includes(a)||y.roleKey.toLowerCase().includes(a)),v=d.filter(y=>!a||y.name.toLowerCase().includes(a)||y.resourceKey.toLowerCase().includes(a)||y.appKey.toLowerCase().includes(a)),T=o?.type==="user"?z.get(o.id):null,L=o?.type==="group"?g.get(o.id):null,N=o?.type==="role"?A.get(o.id):null,Z=o?.type==="resource"?G.get(o.id):null,Q=(y,k)=>{o&&o.type===y&&o.id===k?I(null):I({type:y,id:k})};return l("section",{"data-testid":"authz-graph-view",style:{display:"flex",flexDirection:"column",gap:"1rem",width:"100%"},children:[l("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",flexWrap:"wrap",gap:"0.75rem",backgroundColor:"#f8fafc",padding:"0.75rem 1rem",borderRadius:"8px",border:"1px solid #e2e8f0",width:"100%",boxSizing:"border-box"},children:[l("div",{style:{display:"flex",alignItems:"center",gap:"0.75rem",flexWrap:"wrap"},children:[l("div",{style:{display:"inline-flex",borderRadius:"6px",border:"1px solid #cbd5e1",padding:"2px",backgroundColor:"#ffffff"},children:[e("button",{type:"button",onClick:()=>$("topology"),"data-testid":"switch-mode-topology",style:{padding:"3px 10px",borderRadius:"4px",border:"none",cursor:"pointer",fontSize:"0.75rem",fontWeight:R==="topology"?600:400,backgroundColor:R==="topology"?"#eff6ff":"transparent",color:R==="topology"?"#0284c7":"#64748b",boxShadow:R==="topology"?"0 1px 2px rgba(0,0,0,0.08)":"none"},children:"\u{1F310} \u30C8\u30DD\u30ED\u30B8\u30DE\u30C3\u30D7 (Topology)"}),e("button",{type:"button",onClick:()=>$("columns"),"data-testid":"switch-mode-columns",style:{padding:"3px 10px",borderRadius:"4px",border:"none",cursor:"pointer",fontSize:"0.75rem",fontWeight:R==="columns"?600:400,backgroundColor:R==="columns"?"#eff6ff":"transparent",color:R==="columns"?"#0284c7":"#64748b",boxShadow:R==="columns"?"0 1px 2px rgba(0,0,0,0.08)":"none"},children:"\u{1F4CB} \u30AB\u30E9\u30E0\u4E00\u89A7 (Columns)"})]}),l("div",{style:{display:"flex",gap:"0.4rem",fontSize:"0.75rem",flexWrap:"wrap"},children:[l("span",{style:{backgroundColor:"#e0f2fe",color:"#0369a1",padding:"2px 8px",borderRadius:"12px",fontWeight:600},children:["\u{1F464} \u30E6\u30FC\u30B6\u30FC: ",t.length]}),l("span",{style:{backgroundColor:"#f3e8ff",color:"#6d28d9",padding:"2px 8px",borderRadius:"12px",fontWeight:600},children:["\u{1F465} \u30B0\u30EB\u30FC\u30D7: ",x.length]}),l("span",{style:{backgroundColor:"#e0e7ff",color:"#4338ca",padding:"2px 8px",borderRadius:"12px",fontWeight:600},children:["\u{1F6E1}\uFE0F \u30ED\u30FC\u30EB: ",n.length]}),l("span",{style:{backgroundColor:"#d1fae5",color:"#047857",padding:"2px 8px",borderRadius:"12px",fontWeight:600},children:["\u{1F511} \u30EA\u30BD\u30FC\u30B9: ",d.length]}),l("span",{style:{backgroundColor:"#fef3c7",color:"#b45309",padding:"2px 8px",borderRadius:"12px",fontWeight:600},children:["\u26A1\uFE0F \u6A29\u9650\u8A2D\u5B9A: ",s.length]})]})]}),e("div",{style:{display:"flex",alignItems:"center",gap:"0.5rem"},children:e("input",{type:"text",placeholder:"\u30AD\u30FC\u30EF\u30FC\u30C9\u3067\u7D5E\u308A\u8FBC\u307F...",value:K,onChange:y=>P(y.target.value),"data-testid":"graph-search-input",style:{padding:"5px 10px",borderRadius:"6px",border:"1px solid #cbd5e1",fontSize:"0.8rem",width:"200px"}})})]}),l("div",{style:{minHeight:"38px",height:"38px",display:"flex",alignItems:"center",justifyContent:"space-between",backgroundColor:o?"#eff6ff":"#f8fafc",border:`1px solid ${o?"#bfdbfe":"#e2e8f0"}`,padding:"0 0.8rem",borderRadius:"6px",fontSize:"0.8rem",color:o?"#1e40af":"#64748b",width:"100%",boxSizing:"border-box",transition:"all 0.15s ease"},children:[e("div",{style:{display:"flex",alignItems:"center",gap:"0.4rem",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:o?l(be,{children:[e("span",{children:"\u{1F3AF}"}),e("strong",{children:"\u9078\u629E\u4E2D\u306E\u30CE\u30FC\u30C9:"}),l("span",{children:[T&&`\u30E6\u30FC\u30B6\u30FC\u300C${T.displayName} (${T.email})\u300D\u306B\u95A2\u9023\u3059\u308B\u30D1\u30B9\u3092\u8868\u793A\u4E2D`,L&&`\u30B0\u30EB\u30FC\u30D7\u300C${L.name} (${L.groupKey})\u300D\u306B\u95A2\u9023\u3059\u308B\u30D1\u30B9\u3092\u8868\u793A\u4E2D`,N&&`\u30ED\u30FC\u30EB\u300C${N.name} (${N.roleKey})\u300D\u306B\u95A2\u9023\u3059\u308B\u30D1\u30B9\u3092\u8868\u793A\u4E2D`,Z&&`\u30EA\u30BD\u30FC\u30B9\u300C${Z.name} (${Z.appKey}:${Z.resourceKey})\u300D\u306B\u95A2\u9023\u3059\u308B\u30D1\u30B9\u3092\u8868\u793A\u4E2D`]})]}):l(be,{children:[e("span",{children:"\u{1F4A1}"}),l("span",{children:[e("strong",{children:"\u30D2\u30F3\u30C8:"})," \u30CE\u30FC\u30C9\uFF08\u30EA\u30BD\u30FC\u30B9\u30FB\u30ED\u30FC\u30EB\u30FB\u30B0\u30EB\u30FC\u30D7\u30FB\u30E6\u30FC\u30B6\u30FC\uFF09\u3092\u30AF\u30EA\u30C3\u30AF\u3059\u308B\u3068\u3001\u95A2\u9023\u3059\u308B\u5168\u30D1\u30B9\u304C\u30CF\u30A4\u30E9\u30A4\u30C8\u8868\u793A\u3055\u308C\u307E\u3059"]})]})}),o&&e("button",{type:"button",onClick:()=>I(null),"data-testid":"graph-reset-selection",style:{padding:"3px 8px",borderRadius:"4px",border:"1px solid #93c5fd",backgroundColor:"#ffffff",fontSize:"0.72rem",cursor:"pointer",color:"#1d4ed8",fontWeight:600,whiteSpace:"nowrap",boxShadow:"0 1px 2px rgba(0,0,0,0.05)"},children:"\u2715 \u9078\u629E\u89E3\u9664"})]}),R==="topology"?e(Ct,{users:u,roles:f,resources:v,grants:s,assignments:c,groupRoles:p,groups:S,selectedNode:o,onNodeClick:Q}):l("div",{style:{display:"grid",gridTemplateColumns:"repeat(4, minmax(0, 1fr))",gap:"1rem",alignItems:"start",width:"100%",boxSizing:"border-box"},children:[l("div",{style:{backgroundColor:"#ffffff",borderRadius:"8px",border:"1px solid #e2e8f0",padding:"0.75rem"},children:[l("div",{style:{fontWeight:700,fontSize:"0.85rem",color:"#047857",marginBottom:"0.6rem",display:"flex",alignItems:"center",gap:"0.3rem",borderBottom:"2px solid #a7f3d0",paddingBottom:"0.4rem"},children:[e("span",{children:"\u{1F511}"})," \u30EA\u30BD\u30FC\u30B9 (",v.length,")"]}),l("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",maxHeight:"480px",overflowY:"auto",paddingRight:"4px"},children:[v.length===0&&e("div",{style:{fontSize:"0.8rem",color:"#94a3b8",textAlign:"center",padding:"1rem"},children:"\u5BFE\u8C61\u306E\u30EA\u30BD\u30FC\u30B9\u304C\u3042\u308A\u307E\u305B\u3093"}),v.map(y=>{let k=o?.type==="resource"&&o.id===y.id,C=ae(y.id),j=s.filter(D=>D.resourceId===y.id);return l("button",{type:"button",onClick:()=>Q("resource",y.id),"data-testid":`graph-node-resource-${y.id}`,style:{textAlign:"left",width:"100%",padding:"0.6rem",borderRadius:"6px",border:k?"2px solid #10b981":"1px solid #e2e8f0",backgroundColor:k?"#d1fae5":C?"#ffffff":"#f8fafc",opacity:C?1:.4,cursor:"pointer",transition:"all 0.15s ease",boxShadow:k?"0 2px 4px rgba(16, 185, 129, 0.15)":"none"},children:[e("div",{style:{fontWeight:600,fontSize:"0.82rem",color:"#0f172a"},children:y.name}),l("div",{style:{fontSize:"0.72rem",color:"#64748b",fontFamily:"monospace"},children:[y.appKey,":",y.resourceKey]}),l("div",{style:{display:"flex",flexWrap:"wrap",gap:"0.25rem",marginTop:"0.4rem"},children:[j.map(D=>{let ee=A.get(D.roleId),Y=Pe[D.action]??{bg:"#f1f5f9",text:"#475569",border:"#cbd5e1"};return l("span",{style:{fontSize:"0.68rem",padding:"1px 6px",borderRadius:"4px",backgroundColor:Y.bg,color:Y.text,border:`1px solid ${Y.border}`},children:[ee?.roleKey??`Role#${D.roleId}`,": ",e("strong",{children:D.action})]},D.id)}),j.length===0&&e("span",{style:{fontSize:"0.68rem",color:"#94a3b8"},children:"\u6A29\u9650\u8A2D\u5B9A\u306A\u3057"})]})]},y.id)})]})]}),l("div",{style:{backgroundColor:"#ffffff",borderRadius:"8px",border:"1px solid #e2e8f0",padding:"0.75rem"},children:[l("div",{style:{fontWeight:700,fontSize:"0.85rem",color:"#4338ca",marginBottom:"0.6rem",display:"flex",alignItems:"center",gap:"0.3rem",borderBottom:"2px solid #c7d2fe",paddingBottom:"0.4rem"},children:[e("span",{children:"\u{1F6E1}\uFE0F"})," \u30ED\u30FC\u30EB (",f.length,")"]}),l("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",maxHeight:"480px",overflowY:"auto",paddingRight:"4px"},children:[f.length===0&&e("div",{style:{fontSize:"0.8rem",color:"#94a3b8",textAlign:"center",padding:"1rem"},children:"\u5BFE\u8C61\u306E\u30ED\u30FC\u30EB\u304C\u3042\u308A\u307E\u305B\u3093"}),f.map(y=>{let k=o?.type==="role"&&o.id===y.id,C=re(y.id),j=s.filter(Y=>Y.roleId===y.id),D=c.filter(Y=>Y.roleId===y.id),ee=p.filter(Y=>Y.roleId===y.id);return l("button",{type:"button",onClick:()=>Q("role",y.id),"data-testid":`graph-node-role-${y.id}`,style:{textAlign:"left",width:"100%",padding:"0.6rem",borderRadius:"6px",border:k?"2px solid #6366f1":"1px solid #e2e8f0",backgroundColor:k?"#e0e7ff":C?"#ffffff":"#f8fafc",opacity:C?1:.4,cursor:"pointer",transition:"all 0.15s ease",boxShadow:k?"0 2px 4px rgba(99, 102, 241, 0.15)":"none"},children:[e("div",{style:{fontWeight:600,fontSize:"0.82rem",color:"#0f172a"},children:y.name}),e("div",{style:{fontSize:"0.72rem",color:"#64748b",fontFamily:"monospace"},children:y.roleKey}),l("div",{style:{fontSize:"0.7rem",color:"#475569",marginTop:"0.3rem",display:"flex",gap:"0.5rem"},children:[l("span",{children:["\u6A29\u9650: ",j.length]}),l("span",{children:["\u30B0\u30EB\u30FC\u30D7: ",ee.length]}),l("span",{children:["\u30E6\u30FC\u30B6\u30FC: ",D.length]})]})]},y.id)})]})]}),l("div",{style:{backgroundColor:"#ffffff",borderRadius:"8px",border:"1px solid #e2e8f0",padding:"0.75rem"},children:[l("div",{style:{fontWeight:700,fontSize:"0.85rem",color:"#6d28d9",marginBottom:"0.6rem",display:"flex",alignItems:"center",gap:"0.3rem",borderBottom:"2px solid #ddd6fe",paddingBottom:"0.4rem"},children:[e("span",{children:"\u{1F465}"})," \u30B0\u30EB\u30FC\u30D7 (",S.length,")"]}),l("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",maxHeight:"480px",overflowY:"auto",paddingRight:"4px"},children:[S.length===0&&e("div",{style:{fontSize:"0.8rem",color:"#94a3b8",textAlign:"center",padding:"1rem"},children:"\u5BFE\u8C61\u306E\u30B0\u30EB\u30FC\u30D7\u304C\u3042\u308A\u307E\u305B\u3093"}),S.map(y=>{let k=o?.type==="group"&&o.id===y.id,C=O(y.id),j=p.filter(D=>D.groupId===y.id);return l("button",{type:"button",onClick:()=>Q("group",y.id),"data-testid":`graph-node-group-${y.id}`,style:{textAlign:"left",width:"100%",padding:"0.6rem",borderRadius:"6px",border:k?"2px solid #8b5cf6":"1px solid #e2e8f0",backgroundColor:k?"#f3e8ff":C?"#ffffff":"#f8fafc",opacity:C?1:.4,cursor:"pointer",transition:"all 0.15s ease",boxShadow:k?"0 2px 4px rgba(139, 92, 246, 0.15)":"none"},children:[e("div",{style:{fontWeight:600,fontSize:"0.82rem",color:"#0f172a"},children:y.name}),e("div",{style:{fontSize:"0.72rem",color:"#64748b",fontFamily:"monospace"},children:y.groupKey}),l("div",{style:{display:"flex",flexWrap:"wrap",gap:"0.25rem",marginTop:"0.4rem"},children:[j.map(D=>{let ee=A.get(D.roleId);return l("span",{style:{fontSize:"0.68rem",padding:"1px 6px",borderRadius:"4px",backgroundColor:"#f3e8ff",color:"#6d28d9",border:"1px solid #ddd6fe",fontWeight:600},children:["\u{1F6E1}\uFE0F ",ee?.name??D.roleKey]},`${D.groupId}-${D.roleId}`)}),j.length===0&&e("span",{style:{fontSize:"0.68rem",color:"#94a3b8"},children:"\u30ED\u30FC\u30EB\u672A\u5272\u308A\u5F53\u3066"})]})]},y.id)})]})]}),l("div",{style:{backgroundColor:"#ffffff",borderRadius:"8px",border:"1px solid #e2e8f0",padding:"0.75rem"},children:[l("div",{style:{fontWeight:700,fontSize:"0.85rem",color:"#0369a1",marginBottom:"0.6rem",display:"flex",alignItems:"center",gap:"0.3rem",borderBottom:"2px solid #bae6fd",paddingBottom:"0.4rem"},children:[e("span",{children:"\u{1F464}"})," \u30E6\u30FC\u30B6\u30FC (",u.length,")"]}),l("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",maxHeight:"480px",overflowY:"auto",paddingRight:"4px"},children:[u.length===0&&e("div",{style:{fontSize:"0.8rem",color:"#94a3b8",textAlign:"center",padding:"1rem"},children:"\u5BFE\u8C61\u306E\u30E6\u30FC\u30B6\u30FC\u304C\u3042\u308A\u307E\u305B\u3093"}),u.map(y=>{let k=o?.type==="user"&&o.id===y.id,C=M(y.id),j=c.filter(D=>D.userId===y.id);return l("button",{type:"button",onClick:()=>Q("user",y.id),"data-testid":`graph-node-user-${y.id}`,style:{textAlign:"left",width:"100%",padding:"0.6rem",borderRadius:"6px",border:k?"2px solid #0284c7":"1px solid #e2e8f0",backgroundColor:k?"#e0f2fe":C?"#ffffff":"#f8fafc",opacity:C?1:.4,cursor:"pointer",transition:"all 0.15s ease",boxShadow:k?"0 2px 4px rgba(2, 132, 199, 0.15)":"none"},children:[e("div",{style:{fontWeight:600,fontSize:"0.82rem",color:"#0f172a"},children:y.displayName}),e("div",{style:{fontSize:"0.72rem",color:"#64748b"},children:y.email}),l("div",{style:{display:"flex",flexWrap:"wrap",gap:"0.25rem",marginTop:"0.4rem"},children:[j.map(D=>{let ee=A.get(D.roleId);return l("span",{style:{fontSize:"0.68rem",padding:"1px 6px",borderRadius:"4px",backgroundColor:"#e0f2fe",color:"#0369a1",border:"1px solid #bae6fd",fontWeight:600},children:["\u{1F6E1}\uFE0F ",ee?.name??D.roleKey]},`${D.userId}-${D.roleId}`)}),j.length===0&&e("span",{style:{fontSize:"0.68rem",color:"#94a3b8"},children:"\u76F4\u63A5\u30ED\u30FC\u30EB\u306A\u3057"})]})]},y.id)})]})]})]})]})}var Tt={roles:Ve,resources:St,role_permissions:Pt,user_roles:kt,group_roles:Kt,graph:$t};function yr({renderHeader:t}={}){let{segment:n}=oe(),d=Tt[n]??Ve;return e(He,{renderHeader:t,children:e(d,{})})}function br(t){let n={};for(let d of Object.keys(t)){let s=t[d];n[d]={key:s.key??d,name:s.name,description:s.description}}return n}function xr(t){return Object.values(t).map(n=>n.key)}import{AUTHZ_ACTIONS as Be,assertTenantId as Gt,can as xe,createRequirePermission as Lt,isSameTenant as Dt}from"@aiquants/authz-core";import{redirect as Wt}from"react-router";var Ye="@aiquants/authz-react-router",X=class extends Error{constructor(n){super(`[${Ye}] ${n}`),this.name="AuthzUsageError"}};function Ke(t,n){let d=xe(n,"read"),s=xe(n,"create"),c=xe(n,"update"),p=xe(n,"delete"),x=n?.scopeByAction.read,o=d&&(!x||x.rowScope!==null||x.columnScope!==null);return{resourceKey:t,canRead:d,canCreate:s,canUpdate:c,canDelete:p,canWrite:s||c,readPartial:o,actions:n?Array.from(n.actions):[]}}function ie(t){return t===null?"null":typeof t=="string"?`a string (${JSON.stringify(t)})`:Array.isArray(t)?"an array":`${typeof t} (${String(t)})`}function je(t,n){if(!Array.isArray(t)){let c=typeof t=="string"?` A bare string would be iterated character by character; pass \`{ resourceKeys: [${JSON.stringify(t)}] }\` instead.`:"";throw new X(`${n} must be an array of resource keys, but received ${ie(t)}.${c}`)}let d=new Set,s=[];return t.forEach((c,p)=>{if(typeof c!="string"||c.trim()==="")throw new X(`${n}[${p}] must be a non-empty resource key string, but received ${ie(c)}.`);d.has(c)||(d.add(c),s.push(c))}),s}function Mt(t){if(t==null)return;let n=t;if(n.actions instanceof Set&&typeof n.scopeByAction=="object")throw new X("createAuthz({ getEffectivePermissions }) must resolve to a record keyed by resource key (e.g. getEffectivePermissionsMany from @aiquants/authz-drizzle), but it resolved to a single EffectivePermission. Keeping the single-resource port would deny every resource silently.")}function Nt(t){if(typeof t!="object"||t===null)throw new X(`requirePermission(request, query) requires a query object like { resourceKey: "documents", action: "read" }, but received ${ie(t)}.`);let{resourceKey:n,action:d}=t;if(typeof n!="string"||n.trim()==="")throw new X(`query.resourceKey must be a non-empty string, but received ${ie(n)}.`);if(typeof d!="string"||!Be.includes(d)){let s=d==="write"?' "write" is a derived concept (create \u222A update) and is never guarded directly \u2014 guard "create" or "update".':"";throw new X(`query.action must be one of ${Be.join(" | ")}, but received ${ie(d)}.${s}`)}return{resourceKey:n,action:d}}function Et(t,n){return t!==null&&Dt(n,t.tenantId)?t:null}function Ar(t){if(typeof t.resolveTenantId!="function")throw new X(`createAuthz({ resolveTenantId }) is required: every permission check is scoped to exactly one tenant, but received ${ie(t.resolveTenantId)}.`);if(typeof t.assertTenantMembership!="function")throw new X(`createAuthz({ assertTenantMembership }) is required: resolving a tenant only says which tenant the request named \u2014 it never proves the caller may act as it, so without this port naming another tenant is enough to be authorized inside it. Received ${ie(t.assertTenantMembership)}.`);async function n(o,I){return t.resolveGroupIds?await t.resolveGroupIds(o,I)??void 0:void 0}async function d(o){return Gt(await t.resolveTenantId(o),`${Ye} createAuthz(resolveTenantId)`)}async function s(o,I,K,P){if(I.length===0)return{};let R=await n(o,P),$=await t.getEffectivePermissions({userId:K,tenantId:P,groupIds:R,appKey:t.appKey,resourceKeys:I});return Mt($),Object.fromEntries(I.map(A=>[A,($&&Object.hasOwn($,A)?$[A]:null)??null]))}async function c(o,I,K){let{resourceKey:P,action:R}=Nt(I),$=K?.failureRedirect?()=>{throw Wt(K.failureRedirect)}:t.onDeny,G=await Lt({resolveUserId:t.resolveUserId,resolveTenantId:d,assertTenantMembership:({ctx:g,tenantId:z,userId:M})=>t.assertTenantMembership(g,z,M),getEffectivePermissions:async g=>(await s(o,[g.resourceKey],g.userId,g.tenantId))[g.resourceKey],onDeny:$})(o,{appKey:t.appKey,resourceKey:P,action:R});return{userId:G.userId,tenantId:G.tenantId,scope:G.scope,permission:Ke(P,G.effectivePermission)}}function p(o){if(o?.resourceKeys!==void 0)return{kind:"explicit",keys:je(o.resourceKeys,"getMyPermissions options.resourceKeys")};if(!t.listResourceKeys)throw new X('getMyPermissions(request) needs to know which resources exist. Either pass them explicitly \u2014 getMyPermissions(request, { resourceKeys: ["documents"] }) \u2014 or configure createAuthz({ listResourceKeys }) (e.g. listResourceKeys from @aiquants/authz-drizzle) to report on every registered resource.');return{kind:"all",listResourceKeys:t.listResourceKeys}}async function x(o,I){let K=p(I),P=await t.resolveUserId(o)??null,R=await d(o);if(!await t.assertTenantMembership(o,R,P))return K.kind==="explicit"?Object.fromEntries(K.keys.map(G=>[G,Ke(G,null)])):{};let $=K.kind==="explicit"?K.keys:je(await K.listResourceKeys(o,R)??[],"the listResourceKeys port result"),A=await s(o,$,P,R);return Object.fromEntries($.map(G=>[G,Ke(G,Et(A[G],R))]))}return{requirePermission:c,getMyPermissions:x}}export{yr as AuthzAdminAppView,fr as AuthzErrorBoundary,Pt as AuthzGrantsView,$t as AuthzGraphView,Kt as AuthzGroupRolesView,mr as AuthzLayout,St as AuthzResourcesView,Ve as AuthzRolesView,X as AuthzUsageError,kt as AuthzUserRolesView,de as ErrorAlert,E as Field,Fe as MyPermissionGroupStatus,Re as MyPermissionIndicator,Zt as MyPermissionStatus,Ar as createAuthz,Bt as createAuthzAdminApp,Ne as createAuthzAdminServer,ot as defaultAuthzAdminLabels,br as defineResources,Se as flattenGroupItems,Oe as formatResourceTooltip,bt as getPermissionSummary,Rt as makeAuthzErrorBoundary,ge as resolveLabels,xr as resourceKeysOf,Ke as toPermissionView,i as ui,_e as usePermission};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiquants/authz-react-router",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"description": "React Router (v7 / v8) adapter for @aiquants/authz-core: requirePermission/getMyPermissions guards, usePermission hook, and MyPermissionIndicator component.",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
},
|
|
32
32
|
"license": "MIT",
|
|
33
33
|
"devDependencies": {
|
|
34
|
+
"@aiquants/authz-core": "0.6.1",
|
|
35
|
+
"@aiquants/select-box": "0.9.2",
|
|
34
36
|
"@testing-library/jest-dom": "^6.9.1",
|
|
35
37
|
"@testing-library/react": "^16.3.2",
|
|
36
38
|
"@types/react": "^19.2.7",
|
|
@@ -42,15 +44,13 @@
|
|
|
42
44
|
"rimraf": "^6.1.2",
|
|
43
45
|
"tsup": "^8.5.1",
|
|
44
46
|
"typescript": "^5.9.3",
|
|
45
|
-
"vitest": "^4.1.10"
|
|
46
|
-
"@aiquants/authz-core": "0.6.0",
|
|
47
|
-
"@aiquants/select-box": "0.9.0"
|
|
47
|
+
"vitest": "^4.1.10"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
+
"@aiquants/authz-core": "^0.6.1",
|
|
51
|
+
"@aiquants/select-box": "^0.9.2",
|
|
50
52
|
"react": ">=18",
|
|
51
|
-
"react-router": "^7.0.0 || ^8.0.0"
|
|
52
|
-
"@aiquants/authz-core": "^0.6.0",
|
|
53
|
-
"@aiquants/select-box": "^0.9.0"
|
|
53
|
+
"react-router": "^7.0.0 || ^8.0.0"
|
|
54
54
|
},
|
|
55
55
|
"engines": {
|
|
56
56
|
"node": ">=18.0.0",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"access": "public"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
|
-
"build": "tsup",
|
|
63
|
+
"build": "tsup && node ../../.config/scripts/strip-dts-comments.mjs dist",
|
|
64
64
|
"build:watch": "tsup --watch",
|
|
65
65
|
"dev": "tsup --watch",
|
|
66
66
|
"typecheck": "tsc --noEmit",
|