Mark server summaries dutiesAuthoritative so id 0 stays fail-closed viewer instead of matching names like a legacy local document. Co-authored-by: Cursor <cursoragent@cursor.com>
46 lines
1.6 KiB
TypeScript
46 lines
1.6 KiB
TypeScript
import type { UserRole } from '../types/docgov';
|
|
|
|
export type ResolveCurrentDocRoleInput = {
|
|
currentUser: { id: number; name: string };
|
|
authorId?: number;
|
|
reviewerId?: number;
|
|
approverId?: number;
|
|
author?: string;
|
|
reviewer?: string;
|
|
approver?: string;
|
|
projectPermission?: string;
|
|
isLegacyLocalDoc?: boolean;
|
|
dutiesAuthoritative?: boolean;
|
|
governanceMode?: 'controlled' | 'freeform';
|
|
};
|
|
|
|
function hasAuthoritativeDutyId(input: ResolveCurrentDocRoleInput): boolean {
|
|
return Boolean(input.authorId || input.reviewerId || input.approverId);
|
|
}
|
|
|
|
function isAuthoritativeDutySource(input: ResolveCurrentDocRoleInput): boolean {
|
|
return input.dutiesAuthoritative === true || input.governanceMode === 'controlled';
|
|
}
|
|
|
|
/**
|
|
* 按权威 user id 解析文档职责。未知身份 fail-closed 为 viewer。
|
|
* name 匹配仅用于真正旧本地文档;服务端受控即使 duty id 为 0 也不得按 name 提权。
|
|
*/
|
|
export function resolveCurrentDocRole(input: ResolveCurrentDocRoleInput): UserRole {
|
|
const uid = input.currentUser.id;
|
|
if (isAuthoritativeDutySource(input) || hasAuthoritativeDutyId(input)) {
|
|
if (input.authorId && input.authorId === uid) return 'author';
|
|
if (input.reviewerId && input.reviewerId === uid) return 'reviewer';
|
|
if (input.approverId && input.approverId === uid) return 'approver';
|
|
return 'viewer';
|
|
}
|
|
|
|
if (input.isLegacyLocalDoc) {
|
|
if (input.author && input.author === input.currentUser.name) return 'author';
|
|
if (input.reviewer && input.reviewer === input.currentUser.name) return 'reviewer';
|
|
if (input.approver && input.approver === input.currentUser.name) return 'approver';
|
|
}
|
|
|
|
return 'viewer';
|
|
}
|