Address RBAC review feedback
This commit is contained in:
@@ -17,8 +17,12 @@
|
|||||||
import Report from "@app/components/Report.svelte"
|
import Report from "@app/components/Report.svelte"
|
||||||
import EventShare from "@app/components/EventShare.svelte"
|
import EventShare from "@app/components/EventShare.svelte"
|
||||||
import EventDeleteConfirm from "@app/components/EventDeleteConfirm.svelte"
|
import EventDeleteConfirm from "@app/components/EventDeleteConfirm.svelte"
|
||||||
import {hasNip29, deriveUserIsSpaceAdmin} from "@app/core/state"
|
import {
|
||||||
import {hasPermission} from "@app/core/roles"
|
deriveUserIsSpaceAdmin,
|
||||||
|
deriveHasPermission,
|
||||||
|
ROOM_PERMISSION_DELETE_EVENT,
|
||||||
|
} from "@app/core/roles"
|
||||||
|
import {hasNip29} from "@app/core/state"
|
||||||
import {pushModal} from "@app/util/modal"
|
import {pushModal} from "@app/util/modal"
|
||||||
import {pushToast} from "@app/util/toast"
|
import {pushToast} from "@app/util/toast"
|
||||||
import {makeSpaceChatPath} from "@app/util/routes"
|
import {makeSpaceChatPath} from "@app/util/routes"
|
||||||
@@ -35,7 +39,9 @@
|
|||||||
|
|
||||||
const isRoot = event.kind !== COMMENT
|
const isRoot = event.kind !== COMMENT
|
||||||
const h = getTagValue("h", event.tags)
|
const h = getTagValue("h", event.tags)
|
||||||
const canDelete = h ? hasPermission(url, h, 9005) : deriveUserIsSpaceAdmin(url)
|
const canDelete = h
|
||||||
|
? deriveHasPermission(url, h, ROOM_PERMISSION_DELETE_EVENT)
|
||||||
|
: deriveUserIsSpaceAdmin(url)
|
||||||
|
|
||||||
const report = () => pushModal(Report, {url, event})
|
const report = () => pushModal(Report, {url, event})
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,12 @@
|
|||||||
import ProfileBadges from "@app/components/ProfileBadges.svelte"
|
import ProfileBadges from "@app/components/ProfileBadges.svelte"
|
||||||
import RoleBadge from "@app/components/RoleBadge.svelte"
|
import RoleBadge from "@app/components/RoleBadge.svelte"
|
||||||
import {pubkeyLink, deriveSpaceBannedPubkeyItems} from "@app/core/state"
|
import {pubkeyLink, deriveSpaceBannedPubkeyItems} from "@app/core/state"
|
||||||
import {deriveUserHasSpacePermission, deriveSpaceMemberRoleInfo} from "@app/core/roles"
|
import {
|
||||||
|
deriveUserHasSpacePermission,
|
||||||
|
deriveSpaceMemberRoleInfo,
|
||||||
|
ROOM_PERMISSION_ADD_MEMBER,
|
||||||
|
ROOM_PERMISSION_BAN_USER,
|
||||||
|
} from "@app/core/roles"
|
||||||
import {addSpaceMembers} from "@app/core/commands"
|
import {addSpaceMembers} from "@app/core/commands"
|
||||||
import {pushModal} from "@app/util/modal"
|
import {pushModal} from "@app/util/modal"
|
||||||
import {pushToast} from "@app/util/toast"
|
import {pushToast} from "@app/util/toast"
|
||||||
@@ -46,9 +51,11 @@
|
|||||||
|
|
||||||
const profile = deriveProfile(pubkey, removeUndefined([url]))
|
const profile = deriveProfile(pubkey, removeUndefined([url]))
|
||||||
|
|
||||||
const canBan = url ? deriveUserHasSpacePermission(url, 9009) : readable(false)
|
const canBan = url ? deriveUserHasSpacePermission(url, ROOM_PERMISSION_BAN_USER) : readable(false)
|
||||||
|
|
||||||
const canRestore = url ? deriveUserHasSpacePermission(url, 9000) : readable(false)
|
const canRestore = url
|
||||||
|
? deriveUserHasSpacePermission(url, ROOM_PERMISSION_ADD_MEMBER)
|
||||||
|
: readable(false)
|
||||||
|
|
||||||
const bannedPubkeys = url ? deriveSpaceBannedPubkeyItems(url) : undefined
|
const bannedPubkeys = url ? deriveSpaceBannedPubkeyItems(url) : undefined
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,8 @@
|
|||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import Reaction from "@app/components/Reaction.svelte"
|
import Reaction from "@app/components/Reaction.svelte"
|
||||||
import ReportDetails from "@app/components/ReportDetails.svelte"
|
import ReportDetails from "@app/components/ReportDetails.svelte"
|
||||||
import {REACTION_KINDS, deriveUserIsSpaceAdmin} from "@app/core/state"
|
import {deriveUserIsSpaceAdmin} from "@app/core/roles"
|
||||||
|
import {REACTION_KINDS} from "@app/core/state"
|
||||||
import {pushModal} from "@app/util/modal"
|
import {pushModal} from "@app/util/modal"
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
import Popover from "@lib/components/Popover.svelte"
|
import Popover from "@lib/components/Popover.svelte"
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
import Confirm from "@lib/components/Confirm.svelte"
|
import Confirm from "@lib/components/Confirm.svelte"
|
||||||
import {deriveUserIsSpaceAdmin} from "@app/core/state"
|
import {deriveUserIsSpaceAdmin} from "@app/core/roles"
|
||||||
import {publishDelete, canEnforceNip70} from "@app/core/commands"
|
import {publishDelete, canEnforceNip70} from "@app/core/commands"
|
||||||
import {pushToast} from "@app/util/toast"
|
import {pushToast} from "@app/util/toast"
|
||||||
import {pushModal} from "@app/util/modal"
|
import {pushModal} from "@app/util/modal"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {sortBy} from "@welshman/lib"
|
|
||||||
import {goto} from "$app/navigation"
|
import {goto} from "$app/navigation"
|
||||||
import type {RoomMeta} from "@welshman/util"
|
import type {RoomMeta} from "@welshman/util"
|
||||||
import {displayRelayUrl, makeRoomMeta} from "@welshman/util"
|
import {displayRelayUrl, makeRoomMeta} from "@welshman/util"
|
||||||
@@ -33,11 +32,16 @@
|
|||||||
import RoomEdit from "@app/components/RoomEdit.svelte"
|
import RoomEdit from "@app/components/RoomEdit.svelte"
|
||||||
import RoomName from "@app/components/RoomName.svelte"
|
import RoomName from "@app/components/RoomName.svelte"
|
||||||
import RoomImage from "@app/components/RoomImage.svelte"
|
import RoomImage from "@app/components/RoomImage.svelte"
|
||||||
import {deriveRoomRoles, hasPermission} from "@app/core/roles"
|
import {
|
||||||
|
deriveRoomMembers,
|
||||||
|
deriveRoomRoles,
|
||||||
|
deriveUserIsRoomAdmin,
|
||||||
|
deriveHasPermission,
|
||||||
|
sortRolesDesc,
|
||||||
|
ROOM_PERMISSION_EDIT_META,
|
||||||
|
} from "@app/core/roles"
|
||||||
import {
|
import {
|
||||||
deriveRoom,
|
deriveRoom,
|
||||||
deriveRoomMembers,
|
|
||||||
deriveUserIsRoomAdmin,
|
|
||||||
deriveUserRoomMembershipStatus,
|
deriveUserRoomMembershipStatus,
|
||||||
deriveUserRooms,
|
deriveUserRooms,
|
||||||
deriveShouldNotify,
|
deriveShouldNotify,
|
||||||
@@ -63,7 +67,7 @@
|
|||||||
const members = deriveRoomMembers(url, h)
|
const members = deriveRoomMembers(url, h)
|
||||||
const roomRoles = deriveRoomRoles(url, h)
|
const roomRoles = deriveRoomRoles(url, h)
|
||||||
const userIsAdmin = deriveUserIsRoomAdmin(url, h)
|
const userIsAdmin = deriveUserIsRoomAdmin(url, h)
|
||||||
const canEditMetadata = hasPermission(url, h, 9002)
|
const canEditMetadata = deriveHasPermission(url, h, ROOM_PERMISSION_EDIT_META)
|
||||||
const membershipStatus = deriveUserRoomMembershipStatus(url, h)
|
const membershipStatus = deriveUserRoomMembershipStatus(url, h)
|
||||||
const userRooms = deriveUserRooms(url)
|
const userRooms = deriveUserRooms(url)
|
||||||
|
|
||||||
@@ -71,8 +75,7 @@
|
|||||||
const shouldNotify = deriveShouldNotify(url, h)
|
const shouldNotify = deriveShouldNotify(url, h)
|
||||||
|
|
||||||
const roleRows = $derived.by(() =>
|
const roleRows = $derived.by(() =>
|
||||||
sortBy(
|
sortRolesDesc(
|
||||||
role => -(role.order ?? -Infinity),
|
|
||||||
Array.from($roomRoles.roles.values()).map(role => ({
|
Array.from($roomRoles.roles.values()).map(role => ({
|
||||||
name: role.name,
|
name: role.name,
|
||||||
label: role.label,
|
label: role.label,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
import EventDeleteConfirm from "@app/components/EventDeleteConfirm.svelte"
|
import EventDeleteConfirm from "@app/components/EventDeleteConfirm.svelte"
|
||||||
import {pushModal} from "@app/util/modal"
|
import {pushModal} from "@app/util/modal"
|
||||||
import {pushToast} from "@app/util/toast"
|
import {pushToast} from "@app/util/toast"
|
||||||
import {deriveUserIsSpaceAdmin} from "@app/core/state"
|
import {deriveUserIsSpaceAdmin} from "@app/core/roles"
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
url: string
|
url: string
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {first, sortBy} from "@welshman/lib"
|
import {first, removeUndefined, sortBy} from "@welshman/lib"
|
||||||
import {waitForThunkError, removeRoomMember} from "@welshman/app"
|
import {waitForThunkError, removeRoomMember} from "@welshman/app"
|
||||||
import MenuDots from "@assets/icons/menu-dots.svg?dataurl"
|
import MenuDots from "@assets/icons/menu-dots.svg?dataurl"
|
||||||
import MinusCircle from "@assets/icons/minus-circle.svg?dataurl"
|
import MinusCircle from "@assets/icons/minus-circle.svg?dataurl"
|
||||||
@@ -21,8 +21,15 @@
|
|||||||
import RoomName from "@app/components/RoomName.svelte"
|
import RoomName from "@app/components/RoomName.svelte"
|
||||||
import RoomMembersAdd from "@app/components/RoomMembersAdd.svelte"
|
import RoomMembersAdd from "@app/components/RoomMembersAdd.svelte"
|
||||||
import type {RoomMember} from "@app/core/roles"
|
import type {RoomMember} from "@app/core/roles"
|
||||||
import {deriveRoom, deriveRoomMembers} from "@app/core/state"
|
import {
|
||||||
import {deriveRoomRoles, hasPermission} from "@app/core/roles"
|
deriveRoomMembers,
|
||||||
|
deriveRoomRoles,
|
||||||
|
deriveHasPermission,
|
||||||
|
sortRolesDesc,
|
||||||
|
ROOM_PERMISSION_ADD_MEMBER,
|
||||||
|
ROOM_PERMISSION_REMOVE_MEMBER,
|
||||||
|
} from "@app/core/roles"
|
||||||
|
import {deriveRoom} from "@app/core/state"
|
||||||
import {pushModal} from "@app/util/modal"
|
import {pushModal} from "@app/util/modal"
|
||||||
import {pushToast} from "@app/util/toast"
|
import {pushToast} from "@app/util/toast"
|
||||||
|
|
||||||
@@ -36,8 +43,8 @@
|
|||||||
const room = deriveRoom(url, h)
|
const room = deriveRoom(url, h)
|
||||||
const members = deriveRoomMembers(url, h)
|
const members = deriveRoomMembers(url, h)
|
||||||
const roomRoles = deriveRoomRoles(url, h)
|
const roomRoles = deriveRoomRoles(url, h)
|
||||||
const canAddMembers = hasPermission(url, h, 9000)
|
const canAddMembers = deriveHasPermission(url, h, ROOM_PERMISSION_ADD_MEMBER)
|
||||||
const canRemoveMembers = hasPermission(url, h, 9001)
|
const canRemoveMembers = deriveHasPermission(url, h, ROOM_PERMISSION_REMOVE_MEMBER)
|
||||||
|
|
||||||
const back = () => history.back()
|
const back = () => history.back()
|
||||||
|
|
||||||
@@ -52,8 +59,7 @@
|
|||||||
const getResolvedRoles = (member: RoomMember) =>
|
const getResolvedRoles = (member: RoomMember) =>
|
||||||
removeUndefined(member.roles.map(roleName => $roomRoles.roles.get(roleName)))
|
removeUndefined(member.roles.map(roleName => $roomRoles.roles.get(roleName)))
|
||||||
|
|
||||||
const getPrimaryRole = (member: RoomMember) =>
|
const getPrimaryRole = (member: RoomMember) => first(sortRolesDesc(getResolvedRoles(member)))
|
||||||
first(sortBy(role => -(role.order ?? -Infinity), getResolvedRoles(member)))
|
|
||||||
|
|
||||||
const memberGroups = $derived.by(() => {
|
const memberGroups = $derived.by(() => {
|
||||||
const byRole = new Map<
|
const byRole = new Map<
|
||||||
@@ -102,9 +108,6 @@
|
|||||||
return groups
|
return groups
|
||||||
})
|
})
|
||||||
|
|
||||||
const removeUndefined = <T,>(items: Array<T | undefined>): T[] =>
|
|
||||||
items.filter((item): item is T => item !== undefined)
|
|
||||||
|
|
||||||
const addMember = () => pushModal(RoomMembersAdd, {url, h})
|
const addMember = () => pushModal(RoomMembersAdd, {url, h})
|
||||||
|
|
||||||
const removeMember = (pubkey: string) =>
|
const removeMember = (pubkey: string) =>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
import SpaceRelayStatus from "@app/components/SpaceRelayStatus.svelte"
|
import SpaceRelayStatus from "@app/components/SpaceRelayStatus.svelte"
|
||||||
import RelayDescription from "@app/components/RelayDescription.svelte"
|
import RelayDescription from "@app/components/RelayDescription.svelte"
|
||||||
import ProfileLatest from "@app/components/ProfileLatest.svelte"
|
import ProfileLatest from "@app/components/ProfileLatest.svelte"
|
||||||
import {deriveUserHasSpacePermission} from "@app/core/roles"
|
import {deriveUserHasSpacePermission, ROOM_PERMISSION_EDIT_META} from "@app/core/roles"
|
||||||
import {pushModal} from "@app/util/modal"
|
import {pushModal} from "@app/util/modal"
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
const {url}: Props = $props()
|
const {url}: Props = $props()
|
||||||
const relay = deriveRelay(url)
|
const relay = deriveRelay(url)
|
||||||
const owner = $derived($relay?.pubkey)
|
const owner = $derived($relay?.pubkey)
|
||||||
const canEdit = deriveUserHasSpacePermission(url, 9002)
|
const canEdit = deriveUserHasSpacePermission(url, ROOM_PERMISSION_EDIT_META)
|
||||||
|
|
||||||
const back = () => history.back()
|
const back = () => history.back()
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,13 @@
|
|||||||
deriveSpaceBannedPubkeyItems,
|
deriveSpaceBannedPubkeyItems,
|
||||||
deriveSupportedMethods,
|
deriveSupportedMethods,
|
||||||
} from "@app/core/state"
|
} from "@app/core/state"
|
||||||
import {deriveSpaceMemberRoleInfo, deriveUserHasSpacePermission} from "@app/core/roles"
|
import {
|
||||||
|
deriveSpaceMemberRoleInfo,
|
||||||
|
deriveUserHasSpacePermission,
|
||||||
|
ROOM_PERMISSION_ADD_MEMBER,
|
||||||
|
ROOM_PERMISSION_REMOVE_MEMBER,
|
||||||
|
ROOM_PERMISSION_BAN_USER,
|
||||||
|
} from "@app/core/roles"
|
||||||
import {pushModal} from "@app/util/modal"
|
import {pushModal} from "@app/util/modal"
|
||||||
import {pushToast} from "@app/util/toast"
|
import {pushToast} from "@app/util/toast"
|
||||||
|
|
||||||
@@ -42,9 +48,9 @@
|
|||||||
const members = deriveSpaceMembers(url)
|
const members = deriveSpaceMembers(url)
|
||||||
const bans = deriveSpaceBannedPubkeyItems(url)
|
const bans = deriveSpaceBannedPubkeyItems(url)
|
||||||
const spaceMemberRoles = deriveSpaceMemberRoleInfo(url)
|
const spaceMemberRoles = deriveSpaceMemberRoleInfo(url)
|
||||||
const canAddMember = deriveUserHasSpacePermission(url, 9000)
|
const canAddMember = deriveUserHasSpacePermission(url, ROOM_PERMISSION_ADD_MEMBER)
|
||||||
const canBanByPermission = deriveUserHasSpacePermission(url, 9009)
|
const canBanByPermission = deriveUserHasSpacePermission(url, ROOM_PERMISSION_BAN_USER)
|
||||||
const canUnallowByPermission = deriveUserHasSpacePermission(url, 9001)
|
const canUnallowByPermission = deriveUserHasSpacePermission(url, ROOM_PERMISSION_REMOVE_MEMBER)
|
||||||
const supportedMethods = deriveSupportedMethods(url)
|
const supportedMethods = deriveSupportedMethods(url)
|
||||||
const canBan = $derived(
|
const canBan = $derived(
|
||||||
$canBanByPermission && $supportedMethods.includes(ManagementMethod.BanPubkey),
|
$canBanByPermission && $supportedMethods.includes(ManagementMethod.BanPubkey),
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
import SpaceMenuRoomItem from "@app/components/SpaceMenuRoomItem.svelte"
|
import SpaceMenuRoomItem from "@app/components/SpaceMenuRoomItem.svelte"
|
||||||
import VoiceWidget from "@app/components/VoiceWidget.svelte"
|
import VoiceWidget from "@app/components/VoiceWidget.svelte"
|
||||||
import SocketStatusIndicator from "@app/components/SocketStatusIndicator.svelte"
|
import SocketStatusIndicator from "@app/components/SocketStatusIndicator.svelte"
|
||||||
|
import {deriveUserIsSpaceAdmin} from "@app/core/roles"
|
||||||
import {
|
import {
|
||||||
ENABLE_ZAPS,
|
ENABLE_ZAPS,
|
||||||
CONTENT_KINDS,
|
CONTENT_KINDS,
|
||||||
@@ -50,7 +51,6 @@
|
|||||||
userSpaceUrls,
|
userSpaceUrls,
|
||||||
hasNip29,
|
hasNip29,
|
||||||
deriveUserCanCreateRoom,
|
deriveUserCanCreateRoom,
|
||||||
deriveUserIsSpaceAdmin,
|
|
||||||
deriveEventsForUrl,
|
deriveEventsForUrl,
|
||||||
deriveSpaceActionItems,
|
deriveSpaceActionItems,
|
||||||
notificationSettings,
|
notificationSettings,
|
||||||
|
|||||||
+34
-25
@@ -1,13 +1,35 @@
|
|||||||
import {derived, readable} from "svelte/store"
|
import {derived, readable} from "svelte/store"
|
||||||
import {first, memoize, simpleCache, sortBy, uniq} from "@welshman/lib"
|
import {first, memoize, removeUndefined, simpleCache, sortBy, uniq} from "@welshman/lib"
|
||||||
import {deriveArray, deriveEventsByIdForUrl} from "@welshman/store"
|
import {deriveArray, deriveEventsByIdForUrl} from "@welshman/store"
|
||||||
import {pubkey, repository, tracker, manageRelay} from "@welshman/app"
|
import {pubkey, repository, tracker} from "@welshman/app"
|
||||||
import {ManagementMethod, ROOM_ADMINS, ROOM_MEMBERS, getTagValue, isRelayUrl} from "@welshman/util"
|
import {
|
||||||
|
ROOM_ADD_MEMBER,
|
||||||
|
ROOM_REMOVE_MEMBER,
|
||||||
|
ROOM_EDIT_META,
|
||||||
|
ROOM_DELETE_EVENT,
|
||||||
|
ROOM_ADMINS,
|
||||||
|
ROOM_MEMBERS,
|
||||||
|
getTagValue,
|
||||||
|
isRelayUrl,
|
||||||
|
} from "@welshman/util"
|
||||||
import type {Filter, TrustedEvent} from "@welshman/util"
|
import type {Filter, TrustedEvent} from "@welshman/util"
|
||||||
|
import {deriveSupportedMethods} from "@app/core/state"
|
||||||
|
|
||||||
export const ROOM_ROLES = 39003
|
export const ROOM_ROLES = 39003
|
||||||
|
|
||||||
const ALL_ROOM_PERMISSIONS = [9000, 9001, 9002, 9005, 9009]
|
export const ROOM_PERMISSION_ADD_MEMBER = ROOM_ADD_MEMBER
|
||||||
|
export const ROOM_PERMISSION_REMOVE_MEMBER = ROOM_REMOVE_MEMBER
|
||||||
|
export const ROOM_PERMISSION_EDIT_META = ROOM_EDIT_META
|
||||||
|
export const ROOM_PERMISSION_DELETE_EVENT = ROOM_DELETE_EVENT
|
||||||
|
export const ROOM_PERMISSION_BAN_USER = 9009
|
||||||
|
|
||||||
|
const ALL_ROOM_PERMISSIONS = [
|
||||||
|
ROOM_PERMISSION_ADD_MEMBER,
|
||||||
|
ROOM_PERMISSION_REMOVE_MEMBER,
|
||||||
|
ROOM_PERMISSION_EDIT_META,
|
||||||
|
ROOM_PERMISSION_DELETE_EVENT,
|
||||||
|
ROOM_PERMISSION_BAN_USER,
|
||||||
|
]
|
||||||
|
|
||||||
export type RoleAccess = "read" | "write" | "join"
|
export type RoleAccess = "read" | "write" | "join"
|
||||||
|
|
||||||
@@ -250,11 +272,10 @@ const getMember = (members: RoomMember[], targetPubkey: string) =>
|
|||||||
const getResolvedRoles = (rolesByName: Map<string, RoleDefinition>, roleNames: string[]) =>
|
const getResolvedRoles = (rolesByName: Map<string, RoleDefinition>, roleNames: string[]) =>
|
||||||
removeUndefined(roleNames.map(name => rolesByName.get(name)))
|
removeUndefined(roleNames.map(name => rolesByName.get(name)))
|
||||||
|
|
||||||
const getPrimaryRole = (roles: RoleDefinition[]) =>
|
export const sortRolesDesc = <T extends {order?: number}>(items: T[]) =>
|
||||||
first(sortBy(role => -(role.order ?? -Infinity), roles))
|
sortBy(item => -(item.order ?? -Infinity), items)
|
||||||
|
|
||||||
const removeUndefined = <T>(items: Array<T | undefined>): T[] =>
|
const getPrimaryRole = (roles: RoleDefinition[]) => first(sortRolesDesc(roles))
|
||||||
items.filter((item): item is T => item !== undefined)
|
|
||||||
|
|
||||||
const deriveRoomRoleAssignments = simpleCache(([url, h]: [string, string]) =>
|
const deriveRoomRoleAssignments = simpleCache(([url, h]: [string, string]) =>
|
||||||
derived(
|
derived(
|
||||||
@@ -309,18 +330,6 @@ export const deriveUserPermissions = (url: string, h: string) =>
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const deriveNip86SpaceAdmin = simpleCache(([url]: [string]) =>
|
|
||||||
readable(false, set => {
|
|
||||||
manageRelay(url, {method: ManagementMethod.SupportedMethods, params: []})
|
|
||||||
.then(({result = []}) => {
|
|
||||||
set(Boolean(result.length))
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
set(false)
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
const buildRoomSnapshots = (events: TrustedEvent[]) => {
|
const buildRoomSnapshots = (events: TrustedEvent[]) => {
|
||||||
const latestByH = new Map<
|
const latestByH = new Map<
|
||||||
string,
|
string,
|
||||||
@@ -457,13 +466,13 @@ export const deriveUserIsSpaceAdmin = memoize((url?: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return derived(
|
return derived(
|
||||||
[deriveSpaceRoleState(url), deriveNip86SpaceAdmin(url)],
|
[deriveSpaceRoleState(url), deriveSupportedMethods(url)],
|
||||||
([$spaceRoleState, $nip86Admin]) => {
|
([$spaceRoleState, $supportedMethods]) => {
|
||||||
if ($spaceRoleState.hasPermissionTags) {
|
if ($spaceRoleState.hasPermissionTags) {
|
||||||
return $spaceRoleState.userPermissions.size > 0
|
return $spaceRoleState.userPermissions.size > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return $nip86Admin
|
return $supportedMethods.length > 0
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -501,7 +510,7 @@ export const deriveUserIsRoomAdmin = (url: string, h: string) =>
|
|||||||
([$permissions, $isSpaceAdmin]) => $isSpaceAdmin || $permissions.size > 0,
|
([$permissions, $isSpaceAdmin]) => $isSpaceAdmin || $permissions.size > 0,
|
||||||
)
|
)
|
||||||
|
|
||||||
export const hasPermission = (url: string, h: string, kind: number) =>
|
export const deriveHasPermission = (url: string, h: string, kind: number) =>
|
||||||
derived(
|
derived(
|
||||||
[deriveUserPermissions(url, h), deriveUserIsSpaceAdmin(url)],
|
[deriveUserPermissions(url, h), deriveUserIsSpaceAdmin(url)],
|
||||||
([$permissions, $isSpaceAdmin]) => $isSpaceAdmin || $permissions.has(kind),
|
([$permissions, $isSpaceAdmin]) => $isSpaceAdmin || $permissions.has(kind),
|
||||||
@@ -526,7 +535,7 @@ export const deriveSpaceMemberRoleInfo = (url: string) =>
|
|||||||
const roleInfoByPubkey = new Map<string, SpaceMemberRoleInfo>()
|
const roleInfoByPubkey = new Map<string, SpaceMemberRoleInfo>()
|
||||||
|
|
||||||
for (const [pubkey, roles] of $spaceRoleState.memberRoles.entries()) {
|
for (const [pubkey, roles] of $spaceRoleState.memberRoles.entries()) {
|
||||||
const sortedRoles = sortBy(role => -(role.order ?? -Infinity), roles)
|
const sortedRoles = sortRolesDesc(roles)
|
||||||
const primaryRole = first(sortedRoles)
|
const primaryRole = first(sortedRoles)
|
||||||
|
|
||||||
roleInfoByPubkey.set(pubkey, {
|
roleInfoByPubkey.set(pubkey, {
|
||||||
|
|||||||
+12
-16
@@ -152,11 +152,14 @@ import {checkRelayHasLivekit} from "$lib/livekit"
|
|||||||
import {readFeed} from "@lib/feeds"
|
import {readFeed} from "@lib/feeds"
|
||||||
import {
|
import {
|
||||||
parseRoomMembers,
|
parseRoomMembers,
|
||||||
deriveRoomMembers as deriveRoomMembersByRole,
|
deriveRoomMembers,
|
||||||
deriveRoomAdmins as deriveRoomAdminsByRole,
|
deriveUserIsSpaceAdmin,
|
||||||
deriveUserIsSpaceAdmin as deriveUserIsSpaceAdminByRole,
|
deriveUserIsRoomAdmin,
|
||||||
deriveUserIsRoomAdmin as deriveUserIsRoomAdminByRole,
|
|
||||||
deriveUserSpacePermissions,
|
deriveUserSpacePermissions,
|
||||||
|
ROOM_PERMISSION_ADD_MEMBER,
|
||||||
|
ROOM_PERMISSION_REMOVE_MEMBER,
|
||||||
|
ROOM_PERMISSION_DELETE_EVENT,
|
||||||
|
ROOM_PERMISSION_BAN_USER,
|
||||||
} from "@app/core/roles"
|
} from "@app/core/roles"
|
||||||
import type {RoomMember} from "@app/core/roles"
|
import type {RoomMember} from "@app/core/roles"
|
||||||
|
|
||||||
@@ -820,8 +823,6 @@ export const deriveSpaceMembers = (url: string) =>
|
|||||||
uniq(getTagValues("member", event?.tags ?? [])),
|
uniq(getTagValues("member", event?.tags ?? [])),
|
||||||
)
|
)
|
||||||
|
|
||||||
export const deriveRoomMembers = deriveRoomMembersByRole
|
|
||||||
|
|
||||||
export type BannedPubkeyItem = {
|
export type BannedPubkeyItem = {
|
||||||
pubkey: string
|
pubkey: string
|
||||||
reason: string
|
reason: string
|
||||||
@@ -840,8 +841,6 @@ export const deriveSpaceBannedPubkeyItems = (url: string) => {
|
|||||||
return store
|
return store
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deriveRoomAdmins = deriveRoomAdminsByRole
|
|
||||||
|
|
||||||
const getRoomMembers = (_url: string, h: string, events: TrustedEvent[]) => {
|
const getRoomMembers = (_url: string, h: string, events: TrustedEvent[]) => {
|
||||||
const members = new Set<string>()
|
const members = new Set<string>()
|
||||||
|
|
||||||
@@ -901,11 +900,12 @@ export const deriveSpaceActionItems = (url: string) =>
|
|||||||
getTagValue(e.kind === ROOM_MEMBERS ? "d" : "h", e.tags)
|
getTagValue(e.kind === ROOM_MEMBERS ? "d" : "h", e.tags)
|
||||||
const reports = $events.filter(e => e.kind === REPORT)
|
const reports = $events.filter(e => e.kind === REPORT)
|
||||||
const pendingJoins: TrustedEvent[] = []
|
const pendingJoins: TrustedEvent[] = []
|
||||||
const canReviewReports = $permissions.has(9005) || $permissions.size === 0
|
const canReviewReports =
|
||||||
|
$permissions.has(ROOM_PERMISSION_DELETE_EVENT) || $permissions.size === 0
|
||||||
const canReviewJoins =
|
const canReviewJoins =
|
||||||
$permissions.has(9000) ||
|
$permissions.has(ROOM_PERMISSION_ADD_MEMBER) ||
|
||||||
$permissions.has(9001) ||
|
$permissions.has(ROOM_PERMISSION_REMOVE_MEMBER) ||
|
||||||
$permissions.has(9009) ||
|
$permissions.has(ROOM_PERMISSION_BAN_USER) ||
|
||||||
$permissions.size === 0
|
$permissions.size === 0
|
||||||
|
|
||||||
// Room-level join requests — most recent per pubkey+h
|
// Room-level join requests — most recent per pubkey+h
|
||||||
@@ -978,8 +978,6 @@ export enum MembershipStatus {
|
|||||||
Granted,
|
Granted,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deriveUserIsSpaceAdmin = deriveUserIsSpaceAdminByRole
|
|
||||||
|
|
||||||
export const deriveUserSpaceMembershipStatus = (url: string) => {
|
export const deriveUserSpaceMembershipStatus = (url: string) => {
|
||||||
// Fetch member list and user add/remove events directly in this derivation.
|
// Fetch member list and user add/remove events directly in this derivation.
|
||||||
const memberListFilters: Filter[] = [{kinds: [RELAY_MEMBERS]}]
|
const memberListFilters: Filter[] = [{kinds: [RELAY_MEMBERS]}]
|
||||||
@@ -1042,8 +1040,6 @@ export const deriveUserSpaceMembershipStatus = (url: string) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deriveUserIsRoomAdmin = deriveUserIsRoomAdminByRole
|
|
||||||
|
|
||||||
export const deriveUserRoomMembershipStatus = (url: string, h: string) => {
|
export const deriveUserRoomMembershipStatus = (url: string, h: string) => {
|
||||||
// Fetch the room member list and the current user's add/remove events.
|
// Fetch the room member list and the current user's add/remove events.
|
||||||
const userEventFilters: Filter[] = [{kinds: [ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER], "#h": [h]}]
|
const userEventFilters: Filter[] = [{kinds: [ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER], "#h": [h]}]
|
||||||
|
|||||||
Reference in New Issue
Block a user