@aiquants/authz-react-router 0.2.0 → 0.2.2
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 +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -9
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{data as M,redirect as B}from"react-router";import{AuthzDeniedError as U}from"@aiquants/authz-core";import{data as R,redirect as G}from"react-router";var H={title:"Authorization (RBAC)",myPermission:"Your permissions",tabs:{roles:"Roles",resources:"Resources",role_permissions:"Permissions",user_roles:"User assignments"},common:{add:"Add",save:"Save",delete:"Delete",remove:"Remove",assign:"Assign",grant:"Grant",select:"Select\u2026",active:"\u25CB Enabled",inactive:"\xD7 Disabled",optional:"optional"},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 \xA73.2 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)",user:"user",role:"role",empty:"No assignments",newHeading:"Assign a role",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 v(o){let s=H;return o?{title:o.title??s.title,myPermission:o.myPermission??s.myPermission,tabs:{...s.tabs,...o.tabs},common:{...s.common,...o.common},roles:{...s.roles,...o.roles},resources:{...s.resources,...o.resources},grants:{...s.grants,...o.grants},userRoles:{...s.userRoles,...o.userRoles},error:{...s.error,...o.error},warn:{...s.warn,...o.warn}}:s}var W=o=>o instanceof Response;function x(o){if(W(o))throw o;if(o instanceof U)throw new Response(o.message,{status:403});return R({error:o instanceof Error?o.message:"\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"},{status:400})}function q(o){let s=o.store,i=o.resourceKey??"authz_admin",l=v(o.labels),r=o.requirePermission;async function c(u){await o.requireUser(u);try{return await r(u,{resourceKey:i,action:"read"})}catch(a){throw a instanceof U?new Response(`Forbidden: ${i}`,{status:403}):a}}let n=u=>o.getMyPermissions(u,{resourceKeys:[i]}),g=async u=>{let[a,f]=await Promise.all([s.listRoles(),s.getSelfAdminContext(Number(u))]);return{roles:a,selfAdminRoleIds:f.selfAdminRoleIds,labels:l}},h=async()=>({resources:await s.listResources(),labels:l}),m=async()=>{let[u,a,f]=await Promise.all([s.listGrants(),s.listRoles(),s.listResources()]);return{grants:u,roles:a,resources:f,labels:l}},S=async u=>{let[a,f,p,y]=await Promise.all([s.listUserRoles(),s.listRoles(),s.listUsers(),s.getSelfAdminContext(Number(u))]);return{assignments:a,roles:f,users:p,actorUserId:y.actorUserId,selfAdminRoleIds:y.selfAdminRoleIds,labels:l}};return{labels:l,resourceKey:i,layoutGuard:c,loadMyPermissions:n,layout:{async loader({request:u}){return await c(u),{myPermissions:await n(u),labels:l,adminResourceKey:i}}},index:{loader(){throw G("/authz/roles")}},roles:{data:g,async loader({request:u}){let{userId:a}=await r(u,{resourceKey:i,action:"read"});return g(a)},async action({request:u}){let a=await u.formData(),f=String(a.get("_action"));try{switch(f){case"create":{let{userId:p}=await r(u,{resourceKey:i,action:"create"}),y=String(a.get("roleKey")??"").trim(),w=String(a.get("name")??"").trim();return y&&w?(await s.createRole({roleKey:y,name:w,description:String(a.get("description")??"").trim()||null},String(p)),{ok:!0}):R({error:"role_key \u3068 name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"save":{let{userId:p}=await r(u,{resourceKey:i,action:"update"}),y=String(a.get("name")??"").trim();return y?(await s.updateRole(Number(a.get("id")),{name:y,description:String(a.get("description")??"").trim()||null},String(p)),{ok:!0}):R({error:"name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"toggle":{let{userId:p}=await r(u,{resourceKey:i,action:"update"});return await s.setRoleActive(Number(a.get("id")),a.get("isActive")==="true",String(p)),{ok:!0}}case"delete":return await r(u,{resourceKey:i,action:"delete"}),await s.deleteRole(Number(a.get("id"))),{ok:!0};default:return R({error:"unknown action"},{status:400})}}catch(p){return x(p)}}},resources:{data:h,async loader({request:u}){return await r(u,{resourceKey:i,action:"read"}),h()},async action({request:u}){let a=await u.formData(),f=String(a.get("_action"));try{switch(f){case"create":{let{userId:p}=await r(u,{resourceKey:i,action:"create"}),y=String(a.get("appKey")??"").trim(),w=String(a.get("resourceKey")??"").trim(),N=String(a.get("name")??"").trim();return y&&w&&N?(await s.createResource({appKey:y,resourceKey:w,name:N,description:String(a.get("description")??"").trim()||null},String(p)),{ok:!0}):R({error:"app_key / resource_key / name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"save":{let{userId:p}=await r(u,{resourceKey:i,action:"update"}),y=String(a.get("name")??"").trim();return y?(await s.updateResource(Number(a.get("id")),{name:y,description:String(a.get("description")??"").trim()||null},String(p)),{ok:!0}):R({error:"name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"delete":return await r(u,{resourceKey:i,action:"delete"}),await s.deleteResource(Number(a.get("id"))),{ok:!0};default:return R({error:"unknown action"},{status:400})}}catch(p){return x(p)}}},grants:{data:m,async loader({request:u}){return await r(u,{resourceKey:i,action:"read"}),m()},async action({request:u}){let a=await u.formData(),f=String(a.get("_action"));try{switch(f){case"create":{let{userId:p}=await r(u,{resourceKey:i,action:"create"}),y=Number(a.get("roleId")),w=Number(a.get("resourceId"));return y&&w?(await s.createGrant({roleId:y,resourceId:w,action:String(a.get("action")??""),rowScope:String(a.get("rowScope")??""),columnScope:String(a.get("columnScope")??"")},String(p)),{ok:!0}):R({error:"\u30ED\u30FC\u30EB\u3068\u30EA\u30BD\u30FC\u30B9\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044"},{status:400})}case"save":{let{userId:p}=await r(u,{resourceKey:i,action:"update"});return await s.updateGrant(Number(a.get("id")),{rowScope:String(a.get("rowScope")??""),columnScope:String(a.get("columnScope")??"")},String(p)),{ok:!0}}case"delete":return await r(u,{resourceKey:i,action:"delete"}),await s.deleteGrant(Number(a.get("id"))),{ok:!0};default:return R({error:"unknown action"},{status:400})}}catch(p){return x(p)}}},userRoles:{data:S,async loader({request:u}){let{userId:a}=await r(u,{resourceKey:i,action:"read"});return S(a)},async action({request:u}){let a=await u.formData(),f=String(a.get("_action"));try{switch(f){case"assign":{let{userId:p}=await r(u,{resourceKey:i,action:"create"}),y=Number(a.get("userId")),w=Number(a.get("roleId"));return y&&w?(await s.assignUserRole(y,w,String(p)),{ok:!0}):R({error:"\u30E6\u30FC\u30B6\u30FC\u3068\u30ED\u30FC\u30EB\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044"},{status:400})}case"remove":return await r(u,{resourceKey:i,action:"delete"}),await s.removeUserRole(Number(a.get("userId")),Number(a.get("roleId"))),{ok:!0};default:return R({error:"unknown action"},{status:400})}}catch(p){return x(p)}}}}}function F(o){return String(o["*"]??"").split("/")[0]}function ge(o){let s=q(o),i=o.basePath??"/authz",l=["roles","resources","role_permissions","user_roles"],r={roles:s.roles.data,resources:s.resources.data,role_permissions:s.grants.data,user_roles:s.userRoles.data},c={roles:s.roles.action,resources:s.resources.action,role_permissions:s.grants.action,user_roles:s.userRoles.action};async function n(h){let m=F(h.params);if(!l.includes(m))throw B(`${i}/roles`);let{userId:S}=await s.layoutGuard(h.request),[u,a]=await Promise.all([s.loadMyPermissions(h.request),r[m](S)]);return{segment:m,basePath:i,myPermissions:u,adminResourceKey:s.resourceKey,...a}}async function g(h){let m=F(h.params),S=c[m];return S?S(h):M({error:"unknown action"},{status:400})}return{loader:n,action:g,server:s}}import{jsx as O,jsxs as L}from"react/jsx-runtime";var t={page:{padding:"1.25rem",maxWidth:1120,margin:"0 auto",color:"#0f172a"},table:{borderCollapse:"collapse",width:"100%",fontSize:"0.9rem"},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"},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 b({label:o,hint:s,children:i}){return L("div",{style:{display:"flex",flexDirection:"column",gap:"0.3rem"},children:[L("span",{style:{fontSize:"0.8rem",color:"#475569",fontWeight:600},children:[o,s?L("span",{style:{fontWeight:400,color:"#94a3b8"},children:[" \u2014 ",s]}):null]}),i]})}function z({message:o}){return o?O("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:o}):null}import{AUTHZ_ACTIONS as Q}from"@aiquants/authz-core";import{Form as A,isRouteErrorResponse as Y,NavLink as Z,Outlet as X,useActionData as I,useLoaderData as P,useRouteError as j}from"react-router";function C(o){let s=o?.read?o.readPartial?"partial":"full":"none",i=o?.create&&o?.update?"full":o?.create||o?.update?"partial":"none",l=o?.delete?"full":"none";return{canRead:!!o?.read,canWrite:!!o?.write,canDelete:!!o?.delete,readState:s,writeState:i,deleteState:l}}import{jsx as J,jsxs as K}from"react/jsx-runtime";var _={full:"\u25CB",partial:"\u25B3",none:"\xD7"};function $({permission:o,labels:s,showScopeSummary:i=!0,className:l="authz-permission-indicator"}){let r=C(o),c={read:s?.read??"\u8AAD",write:s?.write??"\u66F8",delete:s?.delete??"\u524A\u9664"};return K("span",{className:l,"data-resource":o?.resourceKey??"",children:[K("span",{"data-perm":"read",title:`${c.read}: ${r.readState}`,children:[c.read,_[r.readState]]}),K("span",{"data-perm":"write",title:`${c.write}: ${r.writeState}`,children:[c.write,_[r.writeState]]}),K("span",{"data-perm":"delete",title:`${c.delete}: ${r.deleteState}`,children:[c.delete,_[r.deleteState]]}),i&&r.readState==="partial"?J("span",{"data-perm":"scope",children:"\uFF08\u90E8\u5206\uFF09"}):null]})}import{jsx as e,jsxs as d}from"react/jsx-runtime";var k=o=>o?.error;function T({children:o}){let{myPermissions:s,labels:i,adminResourceKey:l,basePath:r}=P(),c=r??"/authz",n=[["roles",i.tabs.roles],["resources",i.tabs.resources],["role_permissions",i.tabs.role_permissions],["user_roles",i.tabs.user_roles]];return d("div",{className:"authz-admin",style:t.page,children:[d("header",{style:{display:"flex",alignItems:"baseline",justifyContent:"space-between",gap:"1rem",flexWrap:"wrap"},children:[e("h1",{style:{fontSize:"1.3rem",margin:0,fontWeight:700},children:i.title}),d("span",{style:{fontSize:"0.82rem",color:"#475569",display:"inline-flex",alignItems:"center",gap:"0.4rem"},children:[i.myPermission,": ",e($,{permission:s[l]})]})]}),e("nav",{style:{display:"flex",gap:"0.25rem",borderBottom:"1px solid #e2e8f0",margin:"0.9rem 0 1.25rem"},children:n.map(([g,h])=>e(Z,{to:`${c}/${g}`,style:({isActive:m})=>({padding:"0.5rem 0.9rem",textDecoration:"none",color:m?"#2563eb":"#475569",borderBottom:m?"2px solid #2563eb":"2px solid transparent",marginBottom:-1,fontWeight:m?700:500,fontSize:"0.92rem"}),children:h},g))}),o]})}function Ie(){return e(T,{children:e(X,{})})}function ee(o){let s=v(o).error;return function(){let l=j(),r=Y(l)?l:null,c=r?.status===403,n=c?s.forbiddenTitle:r?`${s.genericTitlePrefix} (${r.status})`:s.genericTitle,g=c?s.forbiddenBody:r?typeof r.data=="string"&&r.data?r.data:r.statusText:s.genericBody;return e("div",{style:t.page,children:d("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:n}),e("p",{style:{color:"#7f1d1d",fontSize:"0.9rem",margin:0,lineHeight:1.7},children:g})]})})}}var ke=ee(),E=(o,s)=>i=>{o&&!window.confirm(s)&&i.preventDefault()};function V(){let{roles:o,selfAdminRoleIds:s,labels:i}=P(),l=i.roles,r=i.common,c=new Set(s??[]);return d("section",{children:[e("h2",{style:t.h2,children:l.heading}),e(z,{message:k(I())}),e("p",{style:t.note,children:l.note}),d("table",{style:t.table,children:[e("thead",{children:d("tr",{children:[e("th",{style:t.th,children:l.roleKey}),e("th",{style:t.th,children:l.name}),e("th",{style:t.th,children:l.description}),e("th",{style:t.th,children:l.activeHeader}),e("th",{style:t.th})]})}),d("tbody",{children:[o.map(n=>d("tr",{children:[e("td",{style:t.td,children:e("span",{style:t.code,children:n.roleKey})}),e("td",{style:t.td,children:e("input",{name:"name",defaultValue:n.name,form:`save-role-${n.id}`,"aria-label":`name-${n.id}`,required:!0,style:t.input})}),e("td",{style:t.td,children:e("input",{name:"description",defaultValue:n.description??"",form:`save-role-${n.id}`,"aria-label":`description-${n.id}`,style:t.input})}),e("td",{style:t.td,children:d(A,{method:"post",style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"toggle"}),e("input",{type:"hidden",name:"id",value:n.id}),e("input",{type:"hidden",name:"isActive",value:String(!n.isActive)}),e("button",{type:"submit",style:t.button,onClick:n.isActive?E(c.has(n.id),i.warn.selfRoleDisable):void 0,children:n.isActive?r.active:r.inactive})]})}),d("td",{style:{...t.td,whiteSpace:"nowrap"},children:[d(A,{method:"post",id:`save-role-${n.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:n.id}),e("button",{type:"submit",style:t.save,children:r.save})]}),d(A,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:n.id}),e("button",{type:"submit",style:t.danger,onClick:E(c.has(n.id),i.warn.selfRoleDelete),children:r.delete})]})]})]},n.id)),o.length===0?e("tr",{children:e("td",{style:t.empty,colSpan:5,children:l.empty})}):null]})]}),e("h3",{style:t.h3,children:l.newHeading}),d(A,{method:"post",style:t.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e(b,{label:l.roleKey,hint:l.hintRoleKey,children:e("input",{name:"roleKey","aria-label":"role_key",required:!0,style:t.input})}),e(b,{label:l.name,children:e("input",{name:"name","aria-label":"name",required:!0,style:t.input})}),e(b,{label:l.description,hint:r.optional,children:e("input",{name:"description","aria-label":"description",style:t.input})}),e("button",{type:"submit",style:t.primary,children:r.add})]})]})}function te(){let{resources:o,labels:s}=P(),i=s.resources,l=s.common;return d("section",{children:[e("h2",{style:t.h2,children:i.heading}),e(z,{message:k(I())}),e("p",{style:t.note,children:i.note}),d("table",{style:t.table,children:[e("thead",{children:d("tr",{children:[e("th",{style:t.th,children:i.appKey}),e("th",{style:t.th,children:i.resourceKey}),e("th",{style:t.th,children:i.name}),e("th",{style:t.th,children:i.description}),e("th",{style:t.th})]})}),d("tbody",{children:[o.map(r=>d("tr",{children:[e("td",{style:t.td,children:e("span",{style:t.code,children:r.appKey})}),e("td",{style:t.td,children:e("span",{style:t.code,children:r.resourceKey})}),e("td",{style:t.td,children:e("input",{name:"name",defaultValue:r.name,form:`save-res-${r.id}`,"aria-label":`name-${r.id}`,required:!0,style:t.input})}),e("td",{style:t.td,children:e("input",{name:"description",defaultValue:r.description??"",form:`save-res-${r.id}`,"aria-label":`description-${r.id}`,style:t.input})}),d("td",{style:{...t.td,whiteSpace:"nowrap"},children:[d(A,{method:"post",id:`save-res-${r.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:r.id}),e("button",{type:"submit",style:t.save,children:l.save})]}),d(A,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:r.id}),e("button",{type:"submit",style:t.danger,children:l.delete})]})]})]},r.id)),o.length===0?e("tr",{children:e("td",{style:t.empty,colSpan:5,children:i.empty})}):null]})]}),e("h3",{style:t.h3,children:i.newHeading}),d(A,{method:"post",style:t.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e(b,{label:i.appKey,hint:i.hintAppKey,children:e("input",{name:"appKey","aria-label":"app_key",required:!0,style:t.input})}),e(b,{label:i.resourceKey,hint:i.hintResourceKey,children:e("input",{name:"resourceKey","aria-label":"resource_key",required:!0,style:t.input})}),e(b,{label:i.name,children:e("input",{name:"name","aria-label":"name",required:!0,style:t.input})}),e(b,{label:i.description,hint:l.optional,children:e("input",{name:"description","aria-label":"description",style:t.input})}),e("button",{type:"submit",style:t.primary,children:l.add})]})]})}function re(){let{grants:o,roles:s,resources:i,labels:l}=P(),r=l.grants,c=l.common;return d("section",{children:[e("h2",{style:t.h2,children:r.heading}),e("p",{style:t.note,children:r.note}),e(z,{message:k(I())}),d("table",{style:t.table,children:[e("thead",{children:d("tr",{children:[e("th",{style:t.th,children:r.role}),e("th",{style:t.th,children:r.resource}),e("th",{style:t.th,children:r.action}),e("th",{style:t.th,children:r.rowScope}),e("th",{style:t.th,children:r.columnScope}),e("th",{style:t.th})]})}),d("tbody",{children:[o.map(n=>d("tr",{children:[e("td",{style:t.td,children:e("span",{style:t.code,children:n.roleKey})}),e("td",{style:t.td,children:d("span",{style:t.code,children:[n.appKey,":",n.resourceKey]})}),e("td",{style:t.td,children:n.action}),e("td",{style:t.td,children:e("textarea",{name:"rowScope",defaultValue:n.rowScope??"",form:`save-grant-${n.id}`,"aria-label":`row_scope-${n.id}`,rows:2,placeholder:r.rowScopePlaceholder,style:t.textarea})}),e("td",{style:t.td,children:e("textarea",{name:"columnScope",defaultValue:n.columnScope??"",form:`save-grant-${n.id}`,"aria-label":`column_scope-${n.id}`,rows:2,placeholder:r.columnScopePlaceholder,style:t.textarea})}),d("td",{style:{...t.td,whiteSpace:"nowrap"},children:[d(A,{method:"post",id:`save-grant-${n.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:n.id}),e("button",{type:"submit",style:t.save,children:c.save})]}),d(A,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:n.id}),e("button",{type:"submit",style:t.danger,children:c.delete})]})]})]},n.id)),o.length===0?e("tr",{children:e("td",{style:t.empty,colSpan:6,children:r.empty})}):null]})]}),e("h3",{style:t.h3,children:r.newHeading}),d(A,{method:"post",style:t.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e(b,{label:r.role,children:d("select",{name:"roleId","aria-label":"role",required:!0,style:t.select,children:[e("option",{value:"",children:r.selectPlaceholder}),s.map(n=>e("option",{value:n.id,children:n.roleKey},n.id))]})}),e(b,{label:r.resource,children:d("select",{name:"resourceId","aria-label":"resource",required:!0,style:t.select,children:[e("option",{value:"",children:r.selectPlaceholder}),i.map(n=>d("option",{value:n.id,children:[n.appKey,":",n.resourceKey]},n.id))]})}),e(b,{label:r.action,children:e("select",{name:"action","aria-label":"action",required:!0,style:t.select,children:Q.map(n=>e("option",{value:n,children:n},n))})}),e(b,{label:r.rowScope,hint:r.rowScopeHint,children:e("textarea",{name:"rowScope","aria-label":"row_scope",rows:2,style:t.textarea,placeholder:'{"filters":[{"field":"\u90E8\u9580CD","op":"in","values":["A"]}]}'})}),e(b,{label:r.columnScope,hint:r.columnScopeHint,children:e("textarea",{name:"columnScope","aria-label":"column_scope",rows:2,style:t.textarea,placeholder:'{"mode":"deny","columns":["\u91D1\u984D"]}'})}),e("button",{type:"submit",style:t.primary,children:c.grant})]})]})}function se(){let{assignments:o,roles:s,users:i,actorUserId:l,selfAdminRoleIds:r,labels:c}=P(),n=c.userRoles,g=c.common,h=new Set(r??[]);return d("section",{children:[e("h2",{style:t.h2,children:n.heading}),e(z,{message:k(I())}),d("table",{style:t.table,children:[e("thead",{children:d("tr",{children:[e("th",{style:t.th,children:n.user}),e("th",{style:t.th,children:n.role}),e("th",{style:t.th})]})}),d("tbody",{children:[o.map(m=>d("tr",{children:[d("td",{style:t.td,children:[m.email,d("span",{style:t.muted,children:["\uFF08",m.displayName,"\uFF09"]})]}),e("td",{style:t.td,children:m.roleKey}),e("td",{style:t.td,children:d(A,{method:"post",style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"remove"}),e("input",{type:"hidden",name:"userId",value:m.userId}),e("input",{type:"hidden",name:"roleId",value:m.roleId}),e("button",{type:"submit",style:t.danger,onClick:E(m.userId===l&&h.has(m.roleId),c.warn.selfAssignmentRemove),children:g.remove})]})})]},`${m.userId}-${m.roleId}`)),o.length===0?e("tr",{children:e("td",{style:t.empty,colSpan:3,children:n.empty})}):null]})]}),e("h3",{style:t.h3,children:n.newHeading}),d(A,{method:"post",style:t.card,children:[e("input",{type:"hidden",name:"_action",value:"assign"}),e(b,{label:n.user,children:d("select",{name:"userId","aria-label":"user",required:!0,style:t.select,children:[e("option",{value:"",children:n.selectPlaceholder}),i.map(m=>e("option",{value:m.id,children:m.email},m.id))]})}),e(b,{label:n.role,children:d("select",{name:"roleId","aria-label":"role",required:!0,style:t.select,children:[e("option",{value:"",children:n.selectPlaceholder}),s.filter(m=>m.roleKey!=="@authenticated"&&m.roleKey!=="@anonymous").map(m=>e("option",{value:m.id,children:m.roleKey},m.id))]})}),e("button",{type:"submit",style:t.primary,children:g.assign})]})]})}var oe={roles:V,resources:te,role_permissions:re,user_roles:se};function De(){let{segment:o}=P(),s=oe[o]??V;return e(T,{children:e(s,{})})}import{can as D,createRequirePermission as ne}from"@aiquants/authz-core";import{redirect as ie}from"react-router";function ae(o,s){let i=D(s,"read"),l=D(s,"create"),r=D(s,"update"),c=D(s,"delete"),n=s?.scopeByAction.read,g=i&&!!n&&(n.rowScope!==null||n.columnScope!==null);return{resourceKey:o,read:i,create:l,update:r,delete:c,write:l||r,readPartial:g,actions:s?Array.from(s.actions):[]}}function Ue(o){async function s(l,r,c){let n=c?.failureRedirect?()=>{throw ie(c.failureRedirect)}:o.onDeny;return ne({resolveUserId:o.resolveUserId,getEffectivePermissions:o.getEffectivePermissions,onDeny:n})(l,{appKey:o.appKey,resourceKey:r.resourceKey,action:r.action})}async function i(l,r){let c=await o.resolveUserId(l),n={};for(let g of r.resourceKeys){let h=await o.getEffectivePermissions({userId:c??null,appKey:o.appKey,resourceKey:g});n[g]=ae(g,h)}return n}return{requirePermission:s,getMyPermissions:i}}export{De as AuthzAdminAppView,ke as AuthzErrorBoundary,re as AuthzGrantsView,Ie as AuthzLayout,te as AuthzResourcesView,V as AuthzRolesView,se as AuthzUserRolesView,z as ErrorAlert,b as Field,$ as MyPermissionIndicator,Ue as createAuthz,ge as createAuthzAdminApp,q as createAuthzAdminServer,H as defaultAuthzAdminLabels,ee as makeAuthzErrorBoundary,v as resolveLabels,ae as toPermissionView,t as ui,C as usePermission};
|
|
1
|
+
import{data as O,redirect as J}from"react-router";import{AUTHZ_ACTIONS as W,AuthzDeniedError as _}from"@aiquants/authz-core";import{data as A,redirect as M}from"react-router";var G={title:"Authorization (RBAC)",myPermission:"Your permissions",tabs:{roles:"Roles",resources:"Resources",role_permissions:"Permissions",user_roles:"User assignments"},common:{add:"Add",save:"Save",delete:"Delete",remove:"Remove",assign:"Assign",grant:"Grant",select:"Select\u2026",active:"\u25CB Enabled",inactive:"\xD7 Disabled",optional:"optional"},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 \xA73.2 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)",user:"user",role:"role",empty:"No assignments",newHeading:"Assign a role",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 K(o){let s=G;return o?{title:o.title??s.title,myPermission:o.myPermission??s.myPermission,tabs:{...s.tabs,...o.tabs},common:{...s.common,...o.common},roles:{...s.roles,...o.roles},resources:{...s.resources,...o.resources},grants:{...s.grants,...o.grants},userRoles:{...s.userRoles,...o.userRoles},error:{...s.error,...o.error},warn:{...s.warn,...o.warn}}:s}var B=o=>o instanceof Response;function x(o){if(B(o))throw o;if(o instanceof _)throw new Response(o.message,{status:403});return A({error:o instanceof Error?o.message:"\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"},{status:400})}function q(o){let s=o.store,i=o.resourceKey??"authz_admin",l=K(o.labels),r=async(u,a)=>{let{userId:h}=await o.requirePermission(u,a);if(h==null)throw new _({appKey:"",resourceKey:a.resourceKey,action:a.action,reason:"unresolved-user",userId:null});return{userId:h}};async function c(u){await o.requireUser(u);try{return await r(u,{resourceKey:i,action:"read"})}catch(a){throw a instanceof _?new Response(`Forbidden: ${i}`,{status:403}):a}}let n=u=>o.getMyPermissions(u,{resourceKeys:[i]}),g=async u=>{let[a,h]=await Promise.all([s.listRoles(),s.getSelfAdminContext(Number(u))]);return{roles:a,selfAdminRoleIds:h.selfAdminRoleIds,labels:l}},b=async()=>({resources:await s.listResources(),labels:l}),m=async()=>{let[u,a,h]=await Promise.all([s.listGrants(),s.listRoles(),s.listResources()]);return{grants:u,roles:a,resources:h,labels:l}},S=async u=>{let[a,h,p,y]=await Promise.all([s.listUserRoles(),s.listRoles(),s.listUsers(),s.getSelfAdminContext(Number(u))]);return{assignments:a,roles:h,users:p,actorUserId:y.actorUserId,selfAdminRoleIds:y.selfAdminRoleIds,labels:l}};return{labels:l,resourceKey:i,layoutGuard:c,loadMyPermissions:n,layout:{async loader({request:u}){return await c(u),{myPermissions:await n(u),labels:l,adminResourceKey:i}}},index:{loader(){throw M("/authz/roles")}},roles:{data:g,async loader({request:u}){let{userId:a}=await r(u,{resourceKey:i,action:"read"});return g(a)},async action({request:u}){let a=await u.formData(),h=String(a.get("_action"));try{switch(h){case"create":{let{userId:p}=await r(u,{resourceKey:i,action:"create"}),y=String(a.get("roleKey")??"").trim(),R=String(a.get("name")??"").trim();return y&&R?(await s.createRole({roleKey:y,name:R,description:String(a.get("description")??"").trim()||null},String(p)),{ok:!0}):A({error:"role_key \u3068 name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"save":{let{userId:p}=await r(u,{resourceKey:i,action:"update"}),y=String(a.get("name")??"").trim();return y?(await s.updateRole(Number(a.get("id")),{name:y,description:String(a.get("description")??"").trim()||null},String(p)),{ok:!0}):A({error:"name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"toggle":{let{userId:p}=await r(u,{resourceKey:i,action:"update"});return await s.setRoleActive(Number(a.get("id")),a.get("isActive")==="true",String(p)),{ok:!0}}case"delete":return await r(u,{resourceKey:i,action:"delete"}),await s.deleteRole(Number(a.get("id"))),{ok:!0};default:return A({error:"unknown action"},{status:400})}}catch(p){return x(p)}}},resources:{data:b,async loader({request:u}){return await r(u,{resourceKey:i,action:"read"}),b()},async action({request:u}){let a=await u.formData(),h=String(a.get("_action"));try{switch(h){case"create":{let{userId:p}=await r(u,{resourceKey:i,action:"create"}),y=String(a.get("appKey")??"").trim(),R=String(a.get("resourceKey")??"").trim(),z=String(a.get("name")??"").trim();return y&&R&&z?(await s.createResource({appKey:y,resourceKey:R,name:z,description:String(a.get("description")??"").trim()||null},String(p)),{ok:!0}):A({error:"app_key / resource_key / name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"save":{let{userId:p}=await r(u,{resourceKey:i,action:"update"}),y=String(a.get("name")??"").trim();return y?(await s.updateResource(Number(a.get("id")),{name:y,description:String(a.get("description")??"").trim()||null},String(p)),{ok:!0}):A({error:"name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"delete":return await r(u,{resourceKey:i,action:"delete"}),await s.deleteResource(Number(a.get("id"))),{ok:!0};default:return A({error:"unknown action"},{status:400})}}catch(p){return x(p)}}},grants:{data:m,async loader({request:u}){return await r(u,{resourceKey:i,action:"read"}),m()},async action({request:u}){let a=await u.formData(),h=String(a.get("_action"));try{switch(h){case"create":{let{userId:p}=await r(u,{resourceKey:i,action:"create"}),y=Number(a.get("roleId")),R=Number(a.get("resourceId"));if(!(y&&R))return A({error:"\u30ED\u30FC\u30EB\u3068\u30EA\u30BD\u30FC\u30B9\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044"},{status:400});let z=String(a.get("action")??"");if(!W.includes(z))return A({error:"\u7121\u52B9\u306A action \u3067\u3059"},{status:400});let H=z;return await s.createGrant({roleId:y,resourceId:R,action:H,rowScope:String(a.get("rowScope")??""),columnScope:String(a.get("columnScope")??"")},String(p)),{ok:!0}}case"save":{let{userId:p}=await r(u,{resourceKey:i,action:"update"});return await s.updateGrant(Number(a.get("id")),{rowScope:String(a.get("rowScope")??""),columnScope:String(a.get("columnScope")??"")},String(p)),{ok:!0}}case"delete":return await r(u,{resourceKey:i,action:"delete"}),await s.deleteGrant(Number(a.get("id"))),{ok:!0};default:return A({error:"unknown action"},{status:400})}}catch(p){return x(p)}}},userRoles:{data:S,async loader({request:u}){let{userId:a}=await r(u,{resourceKey:i,action:"read"});return S(a)},async action({request:u}){let a=await u.formData(),h=String(a.get("_action"));try{switch(h){case"assign":{let{userId:p}=await r(u,{resourceKey:i,action:"create"}),y=Number(a.get("userId")),R=Number(a.get("roleId"));return y&&R?(await s.assignUserRole(y,R,String(p)),{ok:!0}):A({error:"\u30E6\u30FC\u30B6\u30FC\u3068\u30ED\u30FC\u30EB\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044"},{status:400})}case"remove":return await r(u,{resourceKey:i,action:"delete"}),await s.removeUserRole(Number(a.get("userId")),Number(a.get("roleId"))),{ok:!0};default:return A({error:"unknown action"},{status:400})}}catch(p){return x(p)}}}}}function F(o){return String(o["*"]??"").split("/")[0]}function be(o){let s=q(o),i=o.basePath??"/authz",l=["roles","resources","role_permissions","user_roles"],r={roles:s.roles.data,resources:s.resources.data,role_permissions:s.grants.data,user_roles:s.userRoles.data},c={roles:s.roles.action,resources:s.resources.action,role_permissions:s.grants.action,user_roles:s.userRoles.action};async function n(b){let m=F(b.params);if(!l.includes(m))throw J(`${i}/roles`);let{userId:S}=await s.layoutGuard(b.request),[u,a]=await Promise.all([s.loadMyPermissions(b.request),r[m](S)]);return{segment:m,basePath:i,myPermissions:u,adminResourceKey:s.resourceKey,...a}}async function g(b){let m=F(b.params),S=c[m];return S?S(b):O({error:"unknown action"},{status:400})}return{loader:n,action:g,server:s}}import{jsx as Q,jsxs as N}from"react/jsx-runtime";var t={page:{padding:"1.25rem",maxWidth:1120,margin:"0 auto",color:"#0f172a"},table:{borderCollapse:"collapse",width:"100%",fontSize:"0.9rem"},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"},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 f({label:o,hint:s,children:i}){return N("div",{style:{display:"flex",flexDirection:"column",gap:"0.3rem"},children:[N("span",{style:{fontSize:"0.8rem",color:"#475569",fontWeight:600},children:[o,s?N("span",{style:{fontWeight:400,color:"#94a3b8"},children:[" \u2014 ",s]}):null]}),i]})}function v({message:o}){return o?Q("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:o}):null}import{AUTHZ_ACTIONS as Z}from"@aiquants/authz-core";import{Form as w,isRouteErrorResponse as X,NavLink as j,Outlet as ee,useActionData as k,useLoaderData as P,useRouteError as te}from"react-router";function C(o){let s=o?.read?o.readPartial?"partial":"full":"none",i=o?.create&&o?.update?"full":o?.create||o?.update?"partial":"none",l=o?.delete?"full":"none";return{canRead:!!o?.read,canWrite:!!o?.write,canDelete:!!o?.delete,readState:s,writeState:i,deleteState:l}}import{jsx as Y,jsxs as I}from"react/jsx-runtime";var E={full:"\u25CB",partial:"\u25B3",none:"\xD7"};function T({permission:o,labels:s,showScopeSummary:i=!0,className:l="authz-permission-indicator"}){let r=C(o),c={read:s?.read??"\u8AAD",write:s?.write??"\u66F8",delete:s?.delete??"\u524A\u9664"};return I("span",{className:l,"data-resource":o?.resourceKey??"",children:[I("span",{"data-perm":"read",title:`${c.read}: ${r.readState}`,children:[c.read,E[r.readState]]}),I("span",{"data-perm":"write",title:`${c.write}: ${r.writeState}`,children:[c.write,E[r.writeState]]}),I("span",{"data-perm":"delete",title:`${c.delete}: ${r.deleteState}`,children:[c.delete,E[r.deleteState]]}),i&&r.readState==="partial"?Y("span",{"data-perm":"scope",children:"\uFF08\u90E8\u5206\uFF09"}):null]})}import{jsx as e,jsxs as d}from"react/jsx-runtime";var D=o=>o?.error;function $({children:o}){let{myPermissions:s,labels:i,adminResourceKey:l,basePath:r}=P(),c=r??"/authz",n=[["roles",i.tabs.roles],["resources",i.tabs.resources],["role_permissions",i.tabs.role_permissions],["user_roles",i.tabs.user_roles]];return d("div",{className:"authz-admin",style:t.page,children:[d("header",{style:{display:"flex",alignItems:"baseline",justifyContent:"space-between",gap:"1rem",flexWrap:"wrap"},children:[e("h1",{style:{fontSize:"1.3rem",margin:0,fontWeight:700},children:i.title}),d("span",{style:{fontSize:"0.82rem",color:"#475569",display:"inline-flex",alignItems:"center",gap:"0.4rem"},children:[i.myPermission,": ",e(T,{permission:s[l]})]})]}),e("nav",{style:{display:"flex",gap:"0.25rem",borderBottom:"1px solid #e2e8f0",margin:"0.9rem 0 1.25rem"},children:n.map(([g,b])=>e(j,{to:`${c}/${g}`,style:({isActive:m})=>({padding:"0.5rem 0.9rem",textDecoration:"none",color:m?"#2563eb":"#475569",borderBottom:m?"2px solid #2563eb":"2px solid transparent",marginBottom:-1,fontWeight:m?700:500,fontSize:"0.92rem"}),children:b},g))}),o]})}function De(){return e($,{children:e(ee,{})})}function re(o){let s=K(o).error;return function(){let l=te(),r=X(l)?l:null,c=r?.status===403,n=c?s.forbiddenTitle:r?`${s.genericTitlePrefix} (${r.status})`:s.genericTitle,g=c?s.forbiddenBody:r?typeof r.data=="string"&&r.data?r.data:r.statusText:s.genericBody;return e("div",{style:t.page,children:d("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:n}),e("p",{style:{color:"#7f1d1d",fontSize:"0.9rem",margin:0,lineHeight:1.7},children:g})]})})}}var Le=re(),U=(o,s)=>i=>{o&&!window.confirm(s)&&i.preventDefault()};function V(){let{roles:o,selfAdminRoleIds:s,labels:i}=P(),l=i.roles,r=i.common,c=new Set(s??[]);return d("section",{children:[e("h2",{style:t.h2,children:l.heading}),e(v,{message:D(k())}),e("p",{style:t.note,children:l.note}),d("table",{style:t.table,children:[e("thead",{children:d("tr",{children:[e("th",{style:t.th,children:l.roleKey}),e("th",{style:t.th,children:l.name}),e("th",{style:t.th,children:l.description}),e("th",{style:t.th,children:l.activeHeader}),e("th",{style:t.th})]})}),d("tbody",{children:[o.map(n=>d("tr",{children:[e("td",{style:t.td,children:e("span",{style:t.code,children:n.roleKey})}),e("td",{style:t.td,children:e("input",{name:"name",defaultValue:n.name,form:`save-role-${n.id}`,"aria-label":`name-${n.id}`,required:!0,style:t.input})}),e("td",{style:t.td,children:e("input",{name:"description",defaultValue:n.description??"",form:`save-role-${n.id}`,"aria-label":`description-${n.id}`,style:t.input})}),e("td",{style:t.td,children:d(w,{method:"post",style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"toggle"}),e("input",{type:"hidden",name:"id",value:n.id}),e("input",{type:"hidden",name:"isActive",value:String(!n.isActive)}),e("button",{type:"submit",style:t.button,onClick:n.isActive?U(c.has(n.id),i.warn.selfRoleDisable):void 0,children:n.isActive?r.active:r.inactive})]})}),d("td",{style:{...t.td,whiteSpace:"nowrap"},children:[d(w,{method:"post",id:`save-role-${n.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:n.id}),e("button",{type:"submit",style:t.save,children:r.save})]}),d(w,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:n.id}),e("button",{type:"submit",style:t.danger,onClick:U(c.has(n.id),i.warn.selfRoleDelete),children:r.delete})]})]})]},n.id)),o.length===0?e("tr",{children:e("td",{style:t.empty,colSpan:5,children:l.empty})}):null]})]}),e("h3",{style:t.h3,children:l.newHeading}),d(w,{method:"post",style:t.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e(f,{label:l.roleKey,hint:l.hintRoleKey,children:e("input",{name:"roleKey","aria-label":"role_key",required:!0,style:t.input})}),e(f,{label:l.name,children:e("input",{name:"name","aria-label":"name",required:!0,style:t.input})}),e(f,{label:l.description,hint:r.optional,children:e("input",{name:"description","aria-label":"description",style:t.input})}),e("button",{type:"submit",style:t.primary,children:r.add})]})]})}function se(){let{resources:o,labels:s}=P(),i=s.resources,l=s.common;return d("section",{children:[e("h2",{style:t.h2,children:i.heading}),e(v,{message:D(k())}),e("p",{style:t.note,children:i.note}),d("table",{style:t.table,children:[e("thead",{children:d("tr",{children:[e("th",{style:t.th,children:i.appKey}),e("th",{style:t.th,children:i.resourceKey}),e("th",{style:t.th,children:i.name}),e("th",{style:t.th,children:i.description}),e("th",{style:t.th})]})}),d("tbody",{children:[o.map(r=>d("tr",{children:[e("td",{style:t.td,children:e("span",{style:t.code,children:r.appKey})}),e("td",{style:t.td,children:e("span",{style:t.code,children:r.resourceKey})}),e("td",{style:t.td,children:e("input",{name:"name",defaultValue:r.name,form:`save-res-${r.id}`,"aria-label":`name-${r.id}`,required:!0,style:t.input})}),e("td",{style:t.td,children:e("input",{name:"description",defaultValue:r.description??"",form:`save-res-${r.id}`,"aria-label":`description-${r.id}`,style:t.input})}),d("td",{style:{...t.td,whiteSpace:"nowrap"},children:[d(w,{method:"post",id:`save-res-${r.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:r.id}),e("button",{type:"submit",style:t.save,children:l.save})]}),d(w,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:r.id}),e("button",{type:"submit",style:t.danger,children:l.delete})]})]})]},r.id)),o.length===0?e("tr",{children:e("td",{style:t.empty,colSpan:5,children:i.empty})}):null]})]}),e("h3",{style:t.h3,children:i.newHeading}),d(w,{method:"post",style:t.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e(f,{label:i.appKey,hint:i.hintAppKey,children:e("input",{name:"appKey","aria-label":"app_key",required:!0,style:t.input})}),e(f,{label:i.resourceKey,hint:i.hintResourceKey,children:e("input",{name:"resourceKey","aria-label":"resource_key",required:!0,style:t.input})}),e(f,{label:i.name,children:e("input",{name:"name","aria-label":"name",required:!0,style:t.input})}),e(f,{label:i.description,hint:l.optional,children:e("input",{name:"description","aria-label":"description",style:t.input})}),e("button",{type:"submit",style:t.primary,children:l.add})]})]})}function oe(){let{grants:o,roles:s,resources:i,labels:l}=P(),r=l.grants,c=l.common;return d("section",{children:[e("h2",{style:t.h2,children:r.heading}),e("p",{style:t.note,children:r.note}),e(v,{message:D(k())}),d("table",{style:t.table,children:[e("thead",{children:d("tr",{children:[e("th",{style:t.th,children:r.role}),e("th",{style:t.th,children:r.resource}),e("th",{style:t.th,children:r.action}),e("th",{style:t.th,children:r.rowScope}),e("th",{style:t.th,children:r.columnScope}),e("th",{style:t.th})]})}),d("tbody",{children:[o.map(n=>d("tr",{children:[e("td",{style:t.td,children:e("span",{style:t.code,children:n.roleKey})}),e("td",{style:t.td,children:d("span",{style:t.code,children:[n.appKey,":",n.resourceKey]})}),e("td",{style:t.td,children:n.action}),e("td",{style:t.td,children:e("textarea",{name:"rowScope",defaultValue:n.rowScope??"",form:`save-grant-${n.id}`,"aria-label":`row_scope-${n.id}`,rows:2,placeholder:r.rowScopePlaceholder,style:t.textarea})}),e("td",{style:t.td,children:e("textarea",{name:"columnScope",defaultValue:n.columnScope??"",form:`save-grant-${n.id}`,"aria-label":`column_scope-${n.id}`,rows:2,placeholder:r.columnScopePlaceholder,style:t.textarea})}),d("td",{style:{...t.td,whiteSpace:"nowrap"},children:[d(w,{method:"post",id:`save-grant-${n.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:n.id}),e("button",{type:"submit",style:t.save,children:c.save})]}),d(w,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:n.id}),e("button",{type:"submit",style:t.danger,children:c.delete})]})]})]},n.id)),o.length===0?e("tr",{children:e("td",{style:t.empty,colSpan:6,children:r.empty})}):null]})]}),e("h3",{style:t.h3,children:r.newHeading}),d(w,{method:"post",style:t.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e(f,{label:r.role,children:d("select",{name:"roleId","aria-label":"role",required:!0,style:t.select,children:[e("option",{value:"",children:r.selectPlaceholder}),s.map(n=>e("option",{value:n.id,children:n.roleKey},n.id))]})}),e(f,{label:r.resource,children:d("select",{name:"resourceId","aria-label":"resource",required:!0,style:t.select,children:[e("option",{value:"",children:r.selectPlaceholder}),i.map(n=>d("option",{value:n.id,children:[n.appKey,":",n.resourceKey]},n.id))]})}),e(f,{label:r.action,children:e("select",{name:"action","aria-label":"action",required:!0,style:t.select,children:Z.map(n=>e("option",{value:n,children:n},n))})}),e(f,{label:r.rowScope,hint:r.rowScopeHint,children:e("textarea",{name:"rowScope","aria-label":"row_scope",rows:2,style:t.textarea,placeholder:'{"filters":[{"field":"\u90E8\u9580CD","op":"in","values":["A"]}]}'})}),e(f,{label:r.columnScope,hint:r.columnScopeHint,children:e("textarea",{name:"columnScope","aria-label":"column_scope",rows:2,style:t.textarea,placeholder:'{"mode":"deny","columns":["\u91D1\u984D"]}'})}),e("button",{type:"submit",style:t.primary,children:c.grant})]})]})}function ne(){let{assignments:o,roles:s,users:i,actorUserId:l,selfAdminRoleIds:r,labels:c}=P(),n=c.userRoles,g=c.common,b=new Set(r??[]);return d("section",{children:[e("h2",{style:t.h2,children:n.heading}),e(v,{message:D(k())}),d("table",{style:t.table,children:[e("thead",{children:d("tr",{children:[e("th",{style:t.th,children:n.user}),e("th",{style:t.th,children:n.role}),e("th",{style:t.th})]})}),d("tbody",{children:[o.map(m=>d("tr",{children:[d("td",{style:t.td,children:[m.email,d("span",{style:t.muted,children:["\uFF08",m.displayName,"\uFF09"]})]}),e("td",{style:t.td,children:m.roleKey}),e("td",{style:t.td,children:d(w,{method:"post",style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"remove"}),e("input",{type:"hidden",name:"userId",value:m.userId}),e("input",{type:"hidden",name:"roleId",value:m.roleId}),e("button",{type:"submit",style:t.danger,onClick:U(m.userId===l&&b.has(m.roleId),c.warn.selfAssignmentRemove),children:g.remove})]})})]},`${m.userId}-${m.roleId}`)),o.length===0?e("tr",{children:e("td",{style:t.empty,colSpan:3,children:n.empty})}):null]})]}),e("h3",{style:t.h3,children:n.newHeading}),d(w,{method:"post",style:t.card,children:[e("input",{type:"hidden",name:"_action",value:"assign"}),e(f,{label:n.user,children:d("select",{name:"userId","aria-label":"user",required:!0,style:t.select,children:[e("option",{value:"",children:n.selectPlaceholder}),i.map(m=>e("option",{value:m.id,children:m.email},m.id))]})}),e(f,{label:n.role,children:d("select",{name:"roleId","aria-label":"role",required:!0,style:t.select,children:[e("option",{value:"",children:n.selectPlaceholder}),s.filter(m=>m.roleKey!=="@authenticated"&&m.roleKey!=="@anonymous").map(m=>e("option",{value:m.id,children:m.roleKey},m.id))]})}),e("button",{type:"submit",style:t.primary,children:g.assign})]})]})}var ie={roles:V,resources:se,role_permissions:oe,user_roles:ne};function _e(){let{segment:o}=P(),s=ie[o]??V;return e($,{children:e(s,{})})}import{can as L,createRequirePermission as ae}from"@aiquants/authz-core";import{redirect as le}from"react-router";function de(o,s){let i=L(s,"read"),l=L(s,"create"),r=L(s,"update"),c=L(s,"delete"),n=s?.scopeByAction.read,g=i&&!!n&&(n.rowScope!==null||n.columnScope!==null);return{resourceKey:o,read:i,create:l,update:r,delete:c,write:l||r,readPartial:g,actions:s?Array.from(s.actions):[]}}function Fe(o){async function s(l,r,c){let n=c?.failureRedirect?()=>{throw le(c.failureRedirect)}:o.onDeny;return ae({resolveUserId:o.resolveUserId,getEffectivePermissions:o.getEffectivePermissions,onDeny:n})(l,{appKey:o.appKey,resourceKey:r.resourceKey,action:r.action})}async function i(l,r){let c=await o.resolveUserId(l),n={};for(let g of r.resourceKeys){let b=await o.getEffectivePermissions({userId:c??null,appKey:o.appKey,resourceKey:g});n[g]=de(g,b)}return n}return{requirePermission:s,getMyPermissions:i}}export{_e as AuthzAdminAppView,Le as AuthzErrorBoundary,oe as AuthzGrantsView,De as AuthzLayout,se as AuthzResourcesView,V as AuthzRolesView,ne as AuthzUserRolesView,v as ErrorAlert,f as Field,T as MyPermissionIndicator,Fe as createAuthz,be as createAuthzAdminApp,q as createAuthzAdminServer,G as defaultAuthzAdminLabels,re as makeAuthzErrorBoundary,K as resolveLabels,de as toPermissionView,t as ui,C as usePermission};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|