观察类 finding,来自 #5152 的实现。默认部署撞不到 :#5152 之后两个调用点都走 AuthManager.getMembershipPolicy(),返回类型是 MembershipPolicy,词表外的值进不来。留档是因为这两个函数是 @objectstack/plugin-auth 的公开导出(index.ts 的 export * from './reconcile-membership.js'),JS 侧调用方或 cloud 宿主可以绕过类型直接传。
事实(reconcile-membership.ts)
同一个策略字段,两个函数用相反的谓词:
reconcileMembership: if (deps.policy === 'invite-only') return { outcome: 'policy-skip' };
backfillMemberships: if (deps.policy !== 'auto') return { ...summary, reason: 'policy' };
传入 'inviteOnly'(或任何拼错的值)时:
函数
行为
reconcileMembership(注册路径,逐个绑定)
落到 auto 分支,照常自动绑定 —— fail-open
backfillMemberships(回填路径,批量绑定)
判为非 auto,不绑 —— fail-safe
两者对同一个输入给出相反的姿态。真正危险的方向是前者:调用方以为自己关掉了自动绑定,实际上没有。
为什么现在只是 finding
可能的形状
reconcileMembership 改成与回填同向的 fail-safe:if (deps.policy !== 'auto') return { outcome: 'policy-skip' };。一行,语义收紧,且与「墙的默认姿态是有墙」一致。风险:policy-skip 这个 outcome 名对「值非法」这个原因是撒谎,排障时会误导;
两处都在入口用 isMembershipPolicy()(membershipPolicy 无法作为平台设置配置,且注册路径与回填路径读的是两个来源 #5152 新增的类型守卫)显式判非法,给一个独立的 outcome/reason(如 'invalid-policy')并记 error。信息量最足,改动面也最大(ReconcileOutcome 是导出的联合类型,加成员对下游是 minor);
什么都不做——两个谓词的分歧记在这里,等哪天真有外部调用方再说。
倾向 2 :与 #5152 在 settings 边界上采取的姿态(非法值响亮拒绝、不静默强转)一致,且不会让 outcome 名撒谎。但它改的是导出的联合类型,属于契约变更,需要维护者定夺。
Found-during: #5152
观察类 finding,来自 #5152 的实现。默认部署撞不到:#5152 之后两个调用点都走
AuthManager.getMembershipPolicy(),返回类型是MembershipPolicy,词表外的值进不来。留档是因为这两个函数是@objectstack/plugin-auth的公开导出(index.ts的export * from './reconcile-membership.js'),JS 侧调用方或 cloud 宿主可以绕过类型直接传。事实(
reconcile-membership.ts)同一个策略字段,两个函数用相反的谓词:
传入
'inviteOnly'(或任何拼错的值)时:reconcileMembership(注册路径,逐个绑定)auto分支,照常自动绑定 —— fail-openbackfillMemberships(回填路径,批量绑定)auto,不绑 —— fail-safe两者对同一个输入给出相反的姿态。真正危险的方向是前者:调用方以为自己关掉了自动绑定,实际上没有。
为什么现在只是 finding
可能的形状
reconcileMembership改成与回填同向的 fail-safe:if (deps.policy !== 'auto') return { outcome: 'policy-skip' };。一行,语义收紧,且与「墙的默认姿态是有墙」一致。风险:policy-skip这个 outcome 名对「值非法」这个原因是撒谎,排障时会误导;isMembershipPolicy()(membershipPolicy 无法作为平台设置配置,且注册路径与回填路径读的是两个来源 #5152 新增的类型守卫)显式判非法,给一个独立的 outcome/reason(如'invalid-policy')并记error。信息量最足,改动面也最大(ReconcileOutcome是导出的联合类型,加成员对下游是 minor);倾向 2:与 #5152 在 settings 边界上采取的姿态(非法值响亮拒绝、不静默强转)一致,且不会让 outcome 名撒谎。但它改的是导出的联合类型,属于契约变更,需要维护者定夺。
Found-during: #5152