118 lines
3.5 KiB
TypeScript
118 lines
3.5 KiB
TypeScript
import {
|
|
PermissionState,
|
|
RoomPermissionKey,
|
|
RoomPermissionMatrix,
|
|
RoomRole,
|
|
RoomRoleAssignment,
|
|
ROOM_PERMISSION_KEYS
|
|
} from '../../../../shared-kernel';
|
|
import type { MemberIdentity } from '../models/access-control.model';
|
|
|
|
export function normalizeName(name: string): string {
|
|
return name.trim().replace(/\s+/g, ' ');
|
|
}
|
|
|
|
export function compareText(firstValue: string, secondValue: string): number {
|
|
return firstValue.localeCompare(secondValue, undefined, { sensitivity: 'base' });
|
|
}
|
|
|
|
export function uniqueStrings(values: readonly string[]): string[] {
|
|
return Array.from(new Set(values.filter((value) => typeof value === 'string' && value.trim().length > 0).map((value) => value.trim())));
|
|
}
|
|
|
|
export function normalizePermissionState(value: unknown): PermissionState {
|
|
return value === 'allow' || value === 'deny' || value === 'inherit' ? value : 'inherit';
|
|
}
|
|
|
|
export function normalizePermissionMatrix(matrix: RoomPermissionMatrix | undefined): RoomPermissionMatrix {
|
|
const normalized: RoomPermissionMatrix = {};
|
|
|
|
for (const key of ROOM_PERMISSION_KEYS) {
|
|
const value = normalizePermissionState(matrix?.[key]);
|
|
|
|
if (value !== 'inherit') {
|
|
normalized[key] = value;
|
|
}
|
|
}
|
|
|
|
return normalized;
|
|
}
|
|
|
|
export function memberIdentityKey(identity: MemberIdentity | null | undefined): string {
|
|
return identity?.oderId?.trim() || identity?.id?.trim() || '';
|
|
}
|
|
|
|
export function matchesIdentity(identity: MemberIdentity | null | undefined, candidate: Pick<RoomRoleAssignment, 'userId' | 'oderId'>): boolean {
|
|
if (!identity) {
|
|
return false;
|
|
}
|
|
|
|
return !!(
|
|
(identity.id && (candidate.userId === identity.id || candidate.oderId === identity.id)) ||
|
|
(identity.oderId && (candidate.userId === identity.oderId || candidate.oderId === identity.oderId))
|
|
);
|
|
}
|
|
|
|
export function roleSortAscending(firstRole: RoomRole, secondRole: RoomRole): number {
|
|
if (firstRole.position !== secondRole.position) {
|
|
return firstRole.position - secondRole.position;
|
|
}
|
|
|
|
return compareText(firstRole.name, secondRole.name);
|
|
}
|
|
|
|
export function roleSortDescending(firstRole: RoomRole, secondRole: RoomRole): number {
|
|
return roleSortAscending(secondRole, firstRole);
|
|
}
|
|
|
|
export function permissionStateToBoolean(value: PermissionState | undefined, fallbackValue: boolean): boolean {
|
|
if (value === 'allow') {
|
|
return true;
|
|
}
|
|
|
|
if (value === 'deny') {
|
|
return false;
|
|
}
|
|
|
|
return fallbackValue;
|
|
}
|
|
|
|
export function getRolePermissionState(role: RoomRole | undefined, permission: RoomPermissionKey): PermissionState {
|
|
return normalizePermissionState(role?.permissions?.[permission]);
|
|
}
|
|
|
|
export function buildSystemRole(id: string, name: string, position: number, permissions: RoomPermissionMatrix, color: string): RoomRole {
|
|
return {
|
|
id,
|
|
name,
|
|
position,
|
|
color,
|
|
isSystem: true,
|
|
permissions: normalizePermissionMatrix(permissions)
|
|
};
|
|
}
|
|
|
|
export function buildRoleLookup(roles: readonly RoomRole[]): Map<string, RoomRole> {
|
|
return new Map(roles.map((role) => [role.id, role]));
|
|
}
|
|
|
|
export function nextRolePosition(roles: readonly RoomRole[]): number {
|
|
if (roles.length === 0) {
|
|
return 100;
|
|
}
|
|
|
|
return Math.max(...roles.map((role) => role.position)) + 100;
|
|
}
|
|
|
|
export function resolveLegacyAllowState(
|
|
value: boolean | undefined,
|
|
currentState: PermissionState | undefined,
|
|
disabledState: Exclude<PermissionState, 'allow'>
|
|
): PermissionState | undefined {
|
|
if (value === undefined) {
|
|
return currentState;
|
|
}
|
|
|
|
return value ? 'allow' : disabledState;
|
|
}
|