有效权限检查器

SharePoint「Check Permissions」/ Jira Permission Helper 范式的 view-as 检查器(差异化组件——Confluence 连原因链都没做全,业界缺口即本组件定位):固定身份集下拉(来自服务端验证 token,不接受自由输入——Kendra 自报身份教训)→ 结论(有效角色 / 无权限 / 被策略拒绝)+ 扁平原因链(继承 / 直接 / 链接来源逐条列出,不做树)+ 叠加规则说明(多来源并集取权限序最大;deny 一票否决置顶红)。renderKbWhoCan(el, { identities, entries, evaluate? }) → handle { setIdentity(id), getResult() };evaluate 缺省 = kb-core evaluateAcl(先显式 deny → allow 并集 → 默认拒绝 fail-closed)。

身份:固定身份集(服务端 token,不接受自由输入)
可编辑(Editor)
  • 继承 财务部空间 · finance-team · Editor 24 成员 · 由 IT 管理
  • 继承 公司库 · 全体员工 · Viewer org
叠加规则:多来源并集 → Editor;无 Deny 生效

下拉切换身份 → 结论 + 原因链即时重算(并集取权限序最大;deny 一票否决置顶红)

<div id="kb-whocan-demo">  <div class="kb-whocan">    <div class="kb-whocan-bar"><span class="kb-meta">身份:固定身份集(服务端 token,不接受自由输入)</span></div>    <div class="kb-whocan-result">      <div class="kb-whocan-verdict">可编辑(Editor)</div>      <ul class="kb-whocan-chain">        <li class="kb-whocan-reason"><span class="kb-badge">继承</span> 财务部空间 · finance-team · Editor <span class="kb-meta">24 成员 · 由 IT 管理</span></li>        <li class="kb-whocan-reason"><span class="kb-badge">继承</span> 公司库 · 全体员工 · Viewer <span class="kb-meta">org</span></li>      </ul>      <div class="kb-whocan-rule">叠加规则:多来源并集 → Editor;无 Deny 生效</div>    </div>  </div></div><p class="demo-label" id="kb-whocan-log" style="margin-top:8px">下拉切换身份 → 结论 + 原因链即时重算(并集取权限序最大;deny 一票否决置顶红)</p>

安装

bun add @icen.ai/ui

一行引入该组件(CSS 与 behavior 自动带上,无需关心内部 CSS 文件名):

import '@icen.ai/ui/kit/kb-who-can';

也可以用脚手架直接打印引入行:

bunx --bun @icen.ai/ui add kb-who-can

Astro 项目注意:kit 入口里的 CSS import 在页面 <script> 里会被 Astro 的 client bundle 摇掉——请改在布局 frontmatter 里引 CSS(import '@icen.ai/ui/components/kb-perm.css';),JS 行为仍可走 kit。Vite SPA / webpack 项目无此问题。

用法

import { renderKbWhoCan } from '@icen.ai/ui/kit/kb-who-can'; const whocan = renderKbWhoCan(el, {  // 身份集来自服务端验证 token 的固定集合——不接受自由输入(Kendra 自报身份教训)  identities: [    { user: 'zhangsan', label: '张三 · 华东销售部', groups: ['sales-east', 'project-q3'] },    { user: 'wangwu', label: '王五 · 财务部', groups: ['finance-team', 'auditors'] },    { user: 'auditor', label: '系统审计员', groups: ['auditors', 'compliance'] },  ],  entries: aclModel.entries,   // 与 kb-acl 面板同源;evaluate 缺省 = kb-core evaluateAcl  // evaluate: (entries, identity, policy) => myPolicy.evaluate(entries, identity),   // 可注入宿主策略});whocan.setIdentity('wangwu');         // 以 user id 切换 view-as 身份const decision = whocan.getResult();  // KbAclDecision:role / visibility / chain[] / deniedBy? / expiresAt?// 事件:icen:kb-whocan-check {identity, decision}——原因链为扁平清单,不做树(Check Permissions 范式)