aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/permissionsViewer/index.tsx
diff options
context:
space:
mode:
authorNuckyz <61953774+Nuckyz@users.noreply.github.com>2023-05-14 21:33:04 -0300
committerGitHub <noreply@github.com>2023-05-15 02:33:04 +0200
commit64b38348d43040aba9823003b28acbb906e8a7d7 (patch)
tree0b9a0cce4782a4bfeb474ef716b6050dc47c4fcf /src/plugins/permissionsViewer/index.tsx
parent9c1b3a9afd515ea7c38d9c4b4302a60b8d9858ff (diff)
downloadVencord-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.tsx180
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);
+ },
+});