// ==UserScript==
// @name Discord Bot Permission Purger
// @namespace http://github.com/Bluscream
// @version 1.0
// @description Show a confirmation dialog for Discord bot permissions before authorization
// @author Bluscream, phind.com
// @match *://discord.com/oauth2/authorize?*permissions=*
// @grant GM_getValue
// ==/UserScript==
(function() {
'use strict';
const permissionFlags = [
{ id: 0, flag: 1 << 0, description: "Create Instant Invite", channelType: "T, V, S" },
{ id: 1, flag: 1 << 1, description: "Kick Members", channelType: "" },
{ id: 2, flag: 1 << 2, description: "Ban Members", channelType: "" },
{ id: 3, flag: 1 << 3, description: "Administrator", channelType: "" },
{ id: 4, flag: 1 << 4, description: "Manage Channels", channelType: "T, V, S" },
{ id: 5, flag: 1 << 5, description: "Manage Guild", channelType: "" },
{ id: 6, flag: 1 << 6, description: "Add Reactions", channelType: "T, V, S" },
{ id: 7, flag: 1 << 7, description: "View Audit Log", channelType: "" },
{ id: 8, flag: 1 << 8, description: "Priority Speaker", channelType: "V" },
{ id: 9, flag: 1 << 9, description: "Stream", channelType: "V, S" },
{ id: 10, flag: 1 << 10, description: "View Channel", channelType: "T, V, S" },
{ id: 11, flag: 1 << 11, description: "Send Messages", channelType: "T, V, S" },
{ id: 12, flag: 1 << 12, description: "Send TTS Messages", channelType: "T, V, S" },
{ id: 13, flag: 1 << 13, description: "Manage Messages", channelType: "T, V, S" },
{ id: 14, flag: 1 << 14, description: "Embed Links", channelType: "T, V, S" },
{ id: 15, flag: 1 << 15, description: "Attach Files", channelType: "T, V, S" },
{ id: 16, flag: 1 << 16, description: "Read Message History", channelType: "T, V, S" },
{ id: 17, flag: 1 << 17, description: "Mention Everyone", channelType: "T, V, S" },
{ id: 18, flag: 1 << 18, description: "Use External Emojis", channelType: "T, V, S" },
{ id: 19, flag: 1 << 19, description: "View Guild Insights", channelType: "" },
{ id: 20, flag: 1 << 20, description: "Connect", channelType: "V, S" },
{ id: 21, flag: 1 << 21, description: "Speak", channelType: "V" },
{ id: 22, flag: 1 << 22, description: "Mute Members", channelType: "V, S" },
{ id: 23, flag: 1 << 23, description: "Deafen Members", channelType: "V" },
{ id: 24, flag: 1 << 24, description: "Move Members", channelType: "V, S" },
{ id: 25, flag: 1 << 25, description: "Use Voice Activity", channelType: "V" },
{ id: 26, flag: 1 << 26, description: "Change Nickname", channelType: "" },
{ id: 27, flag: 1 << 27, description: "Manage Nicknames", channelType: "" },
{ id: 28, flag: 1 << 28, description: "Manage Roles", channelType: "T, V, S" },
{ id: 29, flag: 1 << 29, description: "Manage Webhooks", channelType: "T, V, S" },
{ id: 30, flag: 1 << 30, description: "Manage Guild Expressions", channelType: "" },
{ id: 31, flag: 1 << 31, description: "Use Application Commands", channelType: "T, V, S" },
{ id: 32, flag: 1 << 32, description: "Request to Speak", channelType: "S" },
{ id: 33, flag: 1 << 33, description: "Manage Events", channelType: "V, S" },
{ id: 34, flag: 1 << 34, description: "Manage Threads", channelType: "T" },
{ id: 35, flag: 1 << 35, description: "Create Public Threads", channelType: "T" },
{ id: 36, flag: 1 << 36, description: "Create Private Threads", channelType: "T" },
{ id: 37, flag: 1 << 37, description: "Use External Stickers", channelType: "T, V, S" },
{ id: 38, flag: 1 << 38, description: "Send Messages in Threads", channelType: "T" },
{ id: 39, flag: 1 << 39, description: "Use Embedded Activities", channelType: "V" },
{ id: 40, flag: 1 << 40, description: "Moderate Members", channelType: "" },
{ id: 41, flag: 1 << 41, description: "View Creator Monetization Analytics", channelType: "" },
{ id: 42, flag: 1 << 42, description: "Use Soundboard", channelType: "V" },
{ id: 43, flag: 1 << 43, description: "Create Guild Expressions", channelType: "" },
{ id: 44, flag: 1 << 44, description: "Create Events", channelType: "V, S" },
{ id: 45, flag: 1 << 45, description: "Use External Sounds", channelType: "V" },
{ id: 46, flag: 1 << 46, description: "Send Voice Messages", channelType: "T, V, S" },
];
async function parsePermissions(raw) {
let permissions = [];
for (const permission of permissionFlags) {
if ((raw & permission.flag) === permission.flag) {
permissions.push(permission);
}
}
return permissions;
}
function buildRawPermissions(permissions) {
let raw = 0;
for (const permission of permissions) {
raw |= permission.flag;
}
return raw;
}
function showConfirmationDialog(rawPermissions) {
return new Promise((resolve) => {
parsePermissions(rawPermissions).then(permissions => {
console.log(permissions);
const rebuiltPermissions = buildRawPermissions(permissions);
console.log(rebuiltPermissions);
if (rebuiltPermissions !== rawPermissions) {
console.error('rebuilt permissions do not match original permissions');
}
let confirmText = `The bot would have the following ${permissions.length} permissions (${rebuiltPermissions}):\n`;
for (const permission of permissions) {
confirmText += ` - ${permission.flag} ${permission.description}`;
if (permission.channelType) {
confirmText += ` (${permission.channelType})`;
}
confirmText += '\n';
}
console.log(confirmText);
const autoPurge = GM_getValue('Automatically remove bot auth permissions', false);
if (autoPurge) {
resolve(true);
} else {
const confirmation = window.confirm(confirmText);
resolve(confirmation);
}
});
});
}
// Intercept the URL and show confirmation dialog
const url = new URL(window.location.href);
const permissions = parseInt(url.searchParams.get('permissions'), 10);
if (permissions) {
showConfirmationDialog(permissions).then((confirmed) => {
if (confirmed) {
url.searchParams.set('permissions', '0');
window.location.href = url.toString();
}
});
}
})();