blob: 6113cc3f661385d4eb796376b7c9f10911ae9ad7 [file] [log] [blame]
PineaFan0d06edc2023-01-17 22:10:31 +00001import { LoadingEmbed } from "../utils/defaults.js";
2import Discord, { CommandInteraction, ActionRowBuilder, ButtonBuilder, ButtonStyle, StringSelectMenuOptionBuilder, SelectMenuOptionBuilder, StringSelectMenuBuilder } from "discord.js";
PineaFan64486c42022-12-28 09:21:04 +00003import { SlashCommandBuilder } from "@discordjs/builders";
pineafan73a7c4a2022-07-24 10:38:04 +01004import EmojiEmbed from "../utils/generateEmojiEmbed.js";
pineafane23c4ec2022-07-27 21:56:27 +01005import getEmojiByName from "../utils/getEmojiByName.js";
6import createPageIndicator from "../utils/createPageIndicator.js";
7import client from "../utils/client.js";
8import confirmationMessage from "../utils/confirmationMessage.js";
PineaFan0d06edc2023-01-17 22:10:31 +00009import { Embed } from "../utils/defaults.js";
pineafan4f164f32022-02-26 22:07:12 +000010
11const command = new SlashCommandBuilder()
12 .setName("privacy")
Skyler Grey11236ba2022-08-08 21:13:33 +010013 .setDescription("Information and options for you and your server's settings");
pineafan4f164f32022-02-26 22:07:12 +000014
pineafane23c4ec2022-07-27 21:56:27 +010015
pineafanbd02b4a2022-08-05 22:01:38 +010016const callback = async (interaction: CommandInteraction): Promise<void> => {
pineafan63fc5e22022-08-04 22:04:10 +010017 const pages = [
pineafane23c4ec2022-07-27 21:56:27 +010018 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +010019 .setEmbed(
20 new EmojiEmbed()
21 .setTitle("Nucleus Privacy")
22 .setDescription(
23 "Nucleus is a bot that naturally needs to store data about servers.\n" +
24 "We are entirely [open source](https://github.com/ClicksMinutePer/Nucleus), so you can check exactly what we store, and how it works.\n\n" +
25 "If you are a server administrator, you can view the options page in the dropdown under this message.\n\n" +
26 "Any questions about Nucleus, how it works and data stored can be asked in [our server](https://discord.gg/bPaNnxe)."
27 )
28 .setEmoji("NUCLEUS.LOGO")
29 .setStatus("Danger")
pineafane23c4ec2022-07-27 21:56:27 +010030 )
Skyler Grey75ea9172022-08-06 10:22:23 +010031 .setTitle("Welcome")
32 .setDescription("General privacy information")
33 .setPageId(0),
34 new Embed()
35 .setEmbed(
36 new EmojiEmbed()
37 .setTitle("Scanners")
38 .setDescription(
pineafan3a02ea32022-08-11 21:35:04 +010039 "Nucleus uses [unscan](https://rapidapi.com/abcdan/api/unscan/) to scan links, images and files for malware and other threats.\n" +
Skyler Grey75ea9172022-08-06 10:22:23 +010040 'This service\'s [privacy policy](https://unscan.co/policies) is public, and they "do not store or sell your data."'
41 )
42 .setEmoji("NUCLEUS.LOGO")
43 .setStatus("Danger")
44 )
45 .setTitle("Scanners")
46 .setDescription("About Unscan")
47 .setPageId(1),
48 new Embed()
49 .setEmbed(
50 new EmojiEmbed()
51 .setTitle("Link scanning and Transcripts")
52 .setDescription(
53 "**Facebook** - Facebook trackers include data such as your date of birth, and guess your age if not entered, your preferences, who you interact with and more.\n" +
54 "**AMP** - AMP is a technology that allows websites to be served by Google. This means Google can store and track data, and are pushing this to as many pages as possible.\n\n" +
PineaFan0d06edc2023-01-17 22:10:31 +000055 "Transcripts allow you to store all messages sent in a channel. This could be an issue in some cases, as they are hosted on [Pastebin](https://pastebin.com), so a leaked link could show all messages sent in the channel.\n" // TODO: Not on pastebin
Skyler Grey75ea9172022-08-06 10:22:23 +010056 )
57 .setEmoji("NUCLEUS.LOGO")
58 .setStatus("Danger")
59 )
60 .setTitle("Link scanning and Transcripts")
Skyler Grey11236ba2022-08-08 21:13:33 +010061 .setDescription("Regarding Facebook and AMP filter types, and ticket transcripts")
Skyler Grey75ea9172022-08-06 10:22:23 +010062 .setPageId(2)
63 ].concat(
PineaFan0d06edc2023-01-17 22:10:31 +000064 (interaction.member as Discord.GuildMember).permissions.has("Administrator")
Skyler Grey75ea9172022-08-06 10:22:23 +010065 ? [
66 new Embed()
67 .setEmbed(
68 new EmojiEmbed()
69 .setTitle("Options")
Skyler Grey11236ba2022-08-08 21:13:33 +010070 .setDescription("Below are buttons for controlling this servers privacy settings")
Skyler Grey75ea9172022-08-06 10:22:23 +010071 .setEmoji("NUCLEUS.LOGO")
72 .setStatus("Danger")
73 )
74 .setTitle("Options")
75 .setDescription("Options")
76 .setPageId(3)
77 .setComponents([
PineaFan0d06edc2023-01-17 22:10:31 +000078 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -040079 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010080 .setLabel("Clear all data")
81 .setCustomId("clear-all-data")
TheCodedProf21c08592022-09-13 14:14:43 -040082 .setStyle(ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +010083 ])
84 ])
85 ]
86 : []
87 );
88 const m = await interaction.reply({
89 embeds: LoadingEmbed,
90 fetchReply: true,
91 ephemeral: true
92 });
PineaFan0d06edc2023-01-17 22:10:31 +000093 let page = parseInt(client.preloadPage[interaction.channel!.id] ? client.preloadPage[interaction.channel!.id]?.argument! : "0");
pineafane23c4ec2022-07-27 21:56:27 +010094
95 let selectPaneOpen = false;
96 let nextFooter = null;
97
Skyler Greyad002172022-08-16 18:48:26 +010098 let timedOut = false;
99 while (!timedOut) {
PineaFan0d06edc2023-01-17 22:10:31 +0000100 let selectPane: Discord.ActionRowBuilder<ButtonBuilder | StringSelectMenuBuilder>[] = [];
pineafane23c4ec2022-07-27 21:56:27 +0100101
102 if (selectPaneOpen) {
PineaFan0d06edc2023-01-17 22:10:31 +0000103 const options: SelectMenuOptionBuilder[] = [];
Skyler Grey75ea9172022-08-06 10:22:23 +0100104 pages.forEach((embed) => {
105 options.push(
PineaFan0d06edc2023-01-17 22:10:31 +0000106 new StringSelectMenuOptionBuilder({
Skyler Grey75ea9172022-08-06 10:22:23 +0100107 label: embed.title,
108 value: embed.pageId.toString(),
109 description: embed.description || ""
110 })
111 );
pineafan63fc5e22022-08-04 22:04:10 +0100112 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100113 selectPane = [
PineaFan0d06edc2023-01-17 22:10:31 +0000114 new ActionRowBuilder<StringSelectMenuBuilder>().addComponents([
115 new Discord.StringSelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100116 .addOptions(options)
117 .setCustomId("page")
118 .setMaxValues(1)
119 .setPlaceholder("Choose a page...")
120 ])
121 ];
pineafane23c4ec2022-07-27 21:56:27 +0100122 }
PineaFan0d06edc2023-01-17 22:10:31 +0000123 const components: ActionRowBuilder<ButtonBuilder | StringSelectMenuBuilder>[] = selectPane.concat([
124 new ActionRowBuilder<ButtonBuilder>().addComponents(
TheCodedProf21c08592022-09-13 14:14:43 -0400125 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100126 .setCustomId("left")
127 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400128 .setStyle(ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100129 .setDisabled(page === 0),
TheCodedProf21c08592022-09-13 14:14:43 -0400130 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100131 .setCustomId("select")
132 .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400133 .setStyle(selectPaneOpen ? ButtonStyle.Primary : ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100134 .setDisabled(false),
TheCodedProf21c08592022-09-13 14:14:43 -0400135 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100136 .setCustomId("right")
137 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400138 .setStyle(ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100139 .setDisabled(page === pages.length - 1)
PineaFan0d06edc2023-01-17 22:10:31 +0000140 )
Skyler Grey75ea9172022-08-06 10:22:23 +0100141 ]);
PineaFan0d06edc2023-01-17 22:10:31 +0000142 const em = new Discord.EmbedBuilder(pages[page]!.embed);
143 em.setDescription(em.data.description + "\n\n" + createPageIndicator(pages.length, page));
144 if (nextFooter) em.setFooter({ text: nextFooter });
pineafane23c4ec2022-07-27 21:56:27 +0100145 await interaction.editReply({
146 embeds: [em],
PineaFan0d06edc2023-01-17 22:10:31 +0000147 components: components.concat(pages[page]?.componentsToSet ?? [])
pineafane23c4ec2022-07-27 21:56:27 +0100148 });
pineafan63fc5e22022-08-04 22:04:10 +0100149 let i;
pineafane23c4ec2022-07-27 21:56:27 +0100150 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000151 i = await m.awaitMessageComponent({
152 time: 300000,
TheCodedProf267563a2023-01-21 17:00:57 -0500153 filter: (i) => { return i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id && i.message.id === m.id }
PineaFan0d06edc2023-01-17 22:10:31 +0000154 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100155 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100156 timedOut = true;
157 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100158 }
pineafan63fc5e22022-08-04 22:04:10 +0100159 nextFooter = null;
TheCodedProf267563a2023-01-21 17:00:57 -0500160 await i.deferUpdate();
PineaFan0d06edc2023-01-17 22:10:31 +0000161 if (i.customId === "left") {
pineafane23c4ec2022-07-27 21:56:27 +0100162 if (page > 0) page--;
163 selectPaneOpen = false;
PineaFan0d06edc2023-01-17 22:10:31 +0000164 } else if (i.customId === "right") {
pineafane23c4ec2022-07-27 21:56:27 +0100165 if (page < pages.length - 1) page++;
166 selectPaneOpen = false;
PineaFan0d06edc2023-01-17 22:10:31 +0000167 } else if (i.customId === "select") {
pineafane23c4ec2022-07-27 21:56:27 +0100168 selectPaneOpen = !selectPaneOpen;
PineaFan0d06edc2023-01-17 22:10:31 +0000169 } else if (i.customId === "page" && i.isStringSelectMenu()) {
170 page = parseInt(i.values[0]!);
pineafane23c4ec2022-07-27 21:56:27 +0100171 selectPaneOpen = false;
PineaFan0d06edc2023-01-17 22:10:31 +0000172 } else if (i.customId === "clear-all-data") {
pineafan63fc5e22022-08-04 22:04:10 +0100173 const confirmation = await new confirmationMessage(interaction)
pineafane23c4ec2022-07-27 21:56:27 +0100174 .setEmoji("CONTROL.BLOCKCROSS")
175 .setTitle("Clear All Data")
176 .setDescription(
pineafan63fc5e22022-08-04 22:04:10 +0100177 "Are you sure you want to delete all data on this server? This includes your settings and all punishment histories.\n\n" +
Skyler Grey75ea9172022-08-06 10:22:23 +0100178 "**This cannot be undone.**"
pineafane23c4ec2022-07-27 21:56:27 +0100179 )
180 .setColor("Danger")
pineafan63fc5e22022-08-04 22:04:10 +0100181 .send(true);
Skyler Grey75ea9172022-08-06 10:22:23 +0100182 if (confirmation.cancelled) {
TheCodedProf267563a2023-01-21 17:00:57 -0500183 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100184 }
pineafane23c4ec2022-07-27 21:56:27 +0100185 if (confirmation.success) {
PineaFan0d06edc2023-01-17 22:10:31 +0000186 client.database.guilds.delete(interaction.guild!.id);
187 client.database.history.delete(interaction.guild!.id);
TheCodedProf267563a2023-01-21 17:00:57 -0500188 client.database.notes.delete(interaction.guild!.id);
pineafane23c4ec2022-07-27 21:56:27 +0100189 nextFooter = "All data cleared";
190 continue;
191 } else {
192 nextFooter = "No changes were made";
193 continue;
194 }
195 } else {
PineaFan0d06edc2023-01-17 22:10:31 +0000196 const em = new Discord.EmbedBuilder(pages[page]!.embed);
197 em.setDescription(em.data.description + "\n\n" + createPageIndicator(pages.length, page));
Skyler Grey75ea9172022-08-06 10:22:23 +0100198 em.setFooter({ text: "Message closed" });
199 interaction.editReply({ embeds: [em], components: [] });
pineafan63fc5e22022-08-04 22:04:10 +0100200 return;
pineafane23c4ec2022-07-27 21:56:27 +0100201 }
pineafan73a7c4a2022-07-24 10:38:04 +0100202 }
PineaFan0d06edc2023-01-17 22:10:31 +0000203 const em = new Discord.EmbedBuilder(pages[page]!.embed);
204 em.setDescription(em.data.description + "\n\n" + createPageIndicator(pages.length, page));
Skyler Grey75ea9172022-08-06 10:22:23 +0100205 em.setFooter({ text: "Message timed out" });
pineafane23c4ec2022-07-27 21:56:27 +0100206 await interaction.editReply({
207 embeds: [em],
208 components: []
209 });
pineafan63fc5e22022-08-04 22:04:10 +0100210};
pineafan4f164f32022-02-26 22:07:12 +0000211
PineaFan0d06edc2023-01-17 22:10:31 +0000212const check = () => {
pineafan4f164f32022-02-26 22:07:12 +0000213 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100214};
pineafan4f164f32022-02-26 22:07:12 +0000215
216export { command };
217export { callback };
Skyler Grey75ea9172022-08-06 10:22:23 +0100218export { check };