diff options
author | Nuckyz <61953774+Nuckyz@users.noreply.github.com> | 2023-05-14 21:33:04 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-15 02:33:04 +0200 |
commit | 64b38348d43040aba9823003b28acbb906e8a7d7 (patch) | |
tree | 0b9a0cce4782a4bfeb474ef716b6050dc47c4fcf /src/plugins/permissionsViewer/index.tsx | |
parent | 9c1b3a9afd515ea7c38d9c4b4302a60b8d9858ff (diff) | |
download | Vencord-64b38348d43040aba9823003b28acbb906e8a7d7.tar.gz Vencord-64b38348d43040aba9823003b28acbb906e8a7d7.tar.bz2 Vencord-64b38348d43040aba9823003b28acbb906e8a7d7.zip |
feat(plugins): Permissions Viewer (#477)
Co-authored-by: V <vendicated@riseup.net>
Diffstat (limited to 'src/plugins/permissionsViewer/index.tsx')
-rw-r--r-- | src/plugins/permissionsViewer/index.tsx | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/src/plugins/permissionsViewer/index.tsx b/src/plugins/permissionsViewer/index.tsx new file mode 100644 index 0000000..793105a --- /dev/null +++ b/src/plugins/permissionsViewer/index.tsx @@ -0,0 +1,180 @@ +/* + * Vencord, a modification for Discord's desktop app + * Copyright (c) 2023 Vendicated and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +import "./styles.css"; + +import { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu"; +import { definePluginSettings } from "@api/Settings"; +import { Devs } from "@utils/constants"; +import definePlugin, { OptionType } from "@utils/types"; +import { ChannelStore, GuildMemberStore, GuildStore, Menu, PermissionsBits, UserStore } from "@webpack/common"; +import type { Guild, GuildMember } from "discord-types/general"; + +import openRolesAndUsersPermissionsModal, { PermissionType, RoleOrUserPermission } from "./components/RolesAndUsersPermissions"; +import UserPermissions from "./components/UserPermissions"; +import { getSortedRoles } from "./utils"; + +export const enum PermissionsSortOrder { + HighestRole, + LowestRole +} + +const enum MenuItemParentType { + User, + Channel, + Guild +} + +export const settings = definePluginSettings({ + permissionsSortOrder: { + description: "The sort method used for defining which role grants an user a certain permission", + type: OptionType.SELECT, + options: [ + { label: "Highest Role", value: PermissionsSortOrder.HighestRole, default: true }, + { label: "Lowest Role", value: PermissionsSortOrder.LowestRole } + ], + }, + defaultPermissionsDropdownState: { + description: "Whether the permissions dropdown on user popouts should be open by default", + type: OptionType.BOOLEAN, + default: false, + } +}); + +function MenuItem(guildId: string, id?: string, type?: MenuItemParentType) { + return ( + <Menu.MenuItem + id="perm-viewer-permissions" + label="Permissions" + action={() => { + const guild = GuildStore.getGuild(guildId); + + let permissions: RoleOrUserPermission[]; + let header: string; + + switch (type) { + case MenuItemParentType.User: { + const member = GuildMemberStore.getMember(guildId, id!); + + permissions = getSortedRoles(guild, member) + .map(role => ({ + type: PermissionType.Role, + ...role + })); + + if (guild.ownerId === id) { + permissions.push({ + type: PermissionType.Owner, + permissions: Object.values(PermissionsBits).reduce((prev, curr) => prev | curr, 0n) + }); + } + + header = member.nick ?? UserStore.getUser(member.userId).username; + + break; + } + + case MenuItemParentType.Channel: { + const channel = ChannelStore.getChannel(id!); + + permissions = Object.values(channel.permissionOverwrites).map(({ id, allow, deny, type }) => ({ + type: type as PermissionType, + id, + overwriteAllow: allow, + overwriteDeny: deny + })); + + header = channel.name; + + break; + } + + default: { + permissions = Object.values(guild.roles).map(role => ({ + type: PermissionType.Role, + ...role + })); + + header = guild.name; + + break; + } + } + + openRolesAndUsersPermissionsModal(permissions, guild, header); + }} + /> + ); +} + +function makeContextMenuPatch(childId: string, type?: MenuItemParentType): NavContextMenuPatchCallback { + return (children, props) => () => { + if (!props) return children; + + const group = findGroupChildrenByChildId(childId, children); + + if (group) { + switch (type) { + case MenuItemParentType.User: + group.push(MenuItem(props.guildId, props.user.id, type)); + break; + case MenuItemParentType.Channel: + group.push(MenuItem(props.guild.id, props.channel.id, type)); + break; + case MenuItemParentType.Guild: + group.push(MenuItem(props.guild.id)); + break; + } + } + }; +} + +export default definePlugin({ + name: "PermissionsViewer", + description: "View the permissions a user or channel has, and the roles of a server", + authors: [Devs.Nuckyz, Devs.Ven], + settings, + + patches: [ + { + find: ".Messages.BOT_PROFILE_SLASH_COMMANDS", + replacement: { + match: /showBorder:.{0,60}}\),(?<=guild:(\i),guildMember:(\i),.+?)/, + replace: (m, guild, guildMember) => `${m}$self.UserPermissions(${guild},${guildMember}),` + } + } + ], + + UserPermissions: (guild: Guild, guildMember: GuildMember) => <UserPermissions guild={guild} guildMember={guildMember} />, + + userContextMenuPatch: makeContextMenuPatch("roles", MenuItemParentType.User), + channelContextMenuPatch: makeContextMenuPatch("mute-channel", MenuItemParentType.Channel), + guildContextMenuPatch: makeContextMenuPatch("privacy", MenuItemParentType.Guild), + + start() { + addContextMenuPatch("user-context", this.userContextMenuPatch); + addContextMenuPatch("channel-context", this.channelContextMenuPatch); + addContextMenuPatch("guild-context", this.guildContextMenuPatch); + }, + + stop() { + removeContextMenuPatch("user-context", this.userContextMenuPatch); + removeContextMenuPatch("channel-context", this.channelContextMenuPatch); + removeContextMenuPatch("guild-context", this.guildContextMenuPatch); + }, +}); |