forked from coracle/flotilla
Polish RBAC role/member stores and remove state-role cycle
This commit is contained in:
+17
-28
@@ -1,8 +1,9 @@
|
||||
import {derived, readable, type Readable} from "svelte/store"
|
||||
import {first, memoize, removeUndefined, simpleCache, sortBy, uniq} from "@welshman/lib"
|
||||
import {deriveArray, deriveEventsByIdForUrl} from "@welshman/store"
|
||||
import {pubkey, repository, tracker} from "@welshman/app"
|
||||
import {pubkey, repository, tracker, manageRelay} from "@welshman/app"
|
||||
import {
|
||||
ManagementMethod,
|
||||
ROOM_ADD_MEMBER,
|
||||
ROOM_REMOVE_MEMBER,
|
||||
ROOM_EDIT_META,
|
||||
@@ -13,7 +14,6 @@ import {
|
||||
isRelayUrl,
|
||||
} from "@welshman/util"
|
||||
import type {Filter, TrustedEvent} from "@welshman/util"
|
||||
import {deriveSupportedMethods} from "@app/core/state"
|
||||
|
||||
export const ROOM_ROLES = 39003
|
||||
|
||||
@@ -31,6 +31,15 @@ const ALL_ROOM_PERMISSIONS = [
|
||||
ROOM_PERMISSION_BAN_USER,
|
||||
]
|
||||
|
||||
export const deriveSupportedMethods = simpleCache(([url]: [string]) =>
|
||||
readable<ManagementMethod[]>([], set => {
|
||||
manageRelay(url, {
|
||||
method: ManagementMethod.SupportedMethods,
|
||||
params: [],
|
||||
}).then(({result = []}) => set(result))
|
||||
}),
|
||||
)
|
||||
|
||||
export type RoleAccess = "read" | "write" | "join"
|
||||
|
||||
export type RoleDefinition = {
|
||||
@@ -53,13 +62,13 @@ export type RoomMember = {
|
||||
roles: string[]
|
||||
}
|
||||
|
||||
export type MemberRoleInfo = {
|
||||
type MemberRoleInfo = {
|
||||
pubkey: string
|
||||
roles: RoleDefinition[]
|
||||
primaryRole?: RoleDefinition
|
||||
}
|
||||
|
||||
export type MemberRoleGroup = {
|
||||
type MemberRoleGroup = {
|
||||
key: string
|
||||
role?: RoleDefinition
|
||||
members: MemberRoleInfo[]
|
||||
@@ -77,8 +86,6 @@ type RoomSnapshot = {
|
||||
admins: RoomMember[]
|
||||
}
|
||||
|
||||
export type SpaceMemberRoleInfo = MemberRoleInfo
|
||||
|
||||
type SpaceRoleState = {
|
||||
hasPermissionTags: boolean
|
||||
userPermissions: Set<number>
|
||||
@@ -283,14 +290,10 @@ const getResolvedRoles = (rolesByName: Map<string, RoleDefinition>, roleNames: s
|
||||
export const sortRolesDesc = <T extends {order?: number}>(items: T[]) =>
|
||||
sortBy(item => -(item.order ?? -Infinity), items)
|
||||
|
||||
export const getRoleLabel = (role: RoleDefinition) => role.label || role.name
|
||||
|
||||
export const getRolePermissionsLabel = (role: RoleDefinition) => role.permissions.join(", ")
|
||||
|
||||
export const getRoleAccessLabel = (role: RoleDefinition) => Array.from(role.access).join(", ")
|
||||
|
||||
const getPrimaryRole = (roles: RoleDefinition[]) => first(sortRolesDesc(roles))
|
||||
|
||||
const toMemberRoleInfo = (pubkey: string, roles: RoleDefinition[]): MemberRoleInfo => {
|
||||
const sortedRoles = sortRolesDesc(roles)
|
||||
|
||||
@@ -304,7 +307,7 @@ const toMemberRoleInfo = (pubkey: string, roles: RoleDefinition[]): MemberRoleIn
|
||||
const sortMemberRoleInfos = (members: MemberRoleInfo[]) =>
|
||||
sortBy(member => -(member.primaryRole?.order ?? -Infinity), members)
|
||||
|
||||
export const groupMemberRoleInfos = (members: MemberRoleInfo[]) => {
|
||||
const groupMemberRoleInfos = (members: MemberRoleInfo[]) => {
|
||||
const byRole = new Map<string, MemberRoleGroup>()
|
||||
const ungrouped: MemberRoleGroup = {
|
||||
key: "members",
|
||||
@@ -578,19 +581,12 @@ export const deriveHasPermission = (url: string, h: string, kind: number) =>
|
||||
([$permissions, $isSpaceAdmin]) => $isSpaceAdmin || $permissions.has(kind),
|
||||
)
|
||||
|
||||
export const deriveUserRoleColor = (url: string, h: string, targetPubkey: string) =>
|
||||
derived(
|
||||
[deriveUserRoles(url, h, targetPubkey), deriveRoomRoles(url, h)],
|
||||
([$roleNames, $roomRoles]) =>
|
||||
getPrimaryRole(getResolvedRoles($roomRoles.roles, $roleNames))?.color,
|
||||
)
|
||||
|
||||
export const deriveRoomRoleDefinitions = (url: string, h: string) =>
|
||||
derived(deriveRoomRoles(url, h), $roomRoles =>
|
||||
sortRolesDesc(Array.from($roomRoles.roles.values())),
|
||||
)
|
||||
|
||||
export const deriveRoomMemberRoleInfo = (url: string, h: string) =>
|
||||
const deriveRoomMemberRoleInfo = (url: string, h: string) =>
|
||||
derived([deriveRoomMembers(url, h), deriveRoomRoles(url, h)], ([$members, $roomRoles]) =>
|
||||
sortMemberRoleInfos(
|
||||
$members.map(member =>
|
||||
@@ -602,16 +598,9 @@ export const deriveRoomMemberRoleInfo = (url: string, h: string) =>
|
||||
export const deriveGroupedRoomMembers = (url: string, h: string) =>
|
||||
derived(deriveRoomMemberRoleInfo(url, h), $members => groupMemberRoleInfos($members))
|
||||
|
||||
export const getRoleSortKey = (url: string, h: string, targetPubkey: string) =>
|
||||
derived(
|
||||
[deriveUserRoles(url, h, targetPubkey), deriveRoomRoles(url, h)],
|
||||
([$roleNames, $roomRoles]) =>
|
||||
getPrimaryRole(getResolvedRoles($roomRoles.roles, $roleNames))?.order,
|
||||
)
|
||||
|
||||
export const deriveSpaceMemberRoleInfo = (url: string) =>
|
||||
const deriveSpaceMemberRoleInfo = (url: string) =>
|
||||
derived(deriveSpaceRoleState(url), $spaceRoleState => {
|
||||
const roleInfoByPubkey = new Map<string, SpaceMemberRoleInfo>()
|
||||
const roleInfoByPubkey = new Map<string, MemberRoleInfo>()
|
||||
|
||||
for (const [pubkey, roles] of $spaceRoleState.memberRoles.entries()) {
|
||||
roleInfoByPubkey.set(pubkey, toMemberRoleInfo(pubkey, roles))
|
||||
|
||||
Reference in New Issue
Block a user