blob: a427688b72dee6bdc48f1c236b073fae856f60bd [file] [log] [blame]
pineafan63fc5e22022-08-04 22:04:10 +01001import { LoadingEmbed } from "./../utils/defaultEmbeds.js";
TheCodedProf21c08592022-09-13 14:14:43 -04002import Discord, { CommandInteraction, ActionRowBuilder, ButtonBuilder, ButtonStyle } 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";
pineafan4f164f32022-02-26 22:07:12 +00009
10const command = new SlashCommandBuilder()
11 .setName("privacy")
Skyler Grey11236ba2022-08-08 21:13:33 +010012 .setDescription("Information and options for you and your server's settings");
pineafan4f164f32022-02-26 22:07:12 +000013
pineafane23c4ec2022-07-27 21:56:27 +010014class Embed {
TheCodedProf21c08592022-09-13 14:14:43 -040015 embed: Discord.EmbedBuilder;
pineafane23c4ec2022-07-27 21:56:27 +010016 title: string;
pineafan63fc5e22022-08-04 22:04:10 +010017 description = "";
18 pageId = 0;
TheCodedProf21c08592022-09-13 14:14:43 -040019 components?: ActionRowBuilder[] = [];
20 setEmbed(embed: Discord.EmbedBuilder) {
Skyler Grey75ea9172022-08-06 10:22:23 +010021 this.embed = embed;
22 return this;
23 }
24 setTitle(title: string) {
25 this.title = title;
26 return this;
27 }
28 setDescription(description: string) {
29 this.description = description;
30 return this;
31 }
32 setPageId(pageId: number) {
33 this.pageId = pageId;
34 return this;
35 }
TheCodedProf21c08592022-09-13 14:14:43 -040036 setComponents(components: ActionRowBuilder[]) {
Skyler Grey75ea9172022-08-06 10:22:23 +010037 this.components = components;
38 return this;
39 }
pineafane23c4ec2022-07-27 21:56:27 +010040}
41
pineafanbd02b4a2022-08-05 22:01:38 +010042const callback = async (interaction: CommandInteraction): Promise<void> => {
pineafan63fc5e22022-08-04 22:04:10 +010043 const pages = [
pineafane23c4ec2022-07-27 21:56:27 +010044 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +010045 .setEmbed(
46 new EmojiEmbed()
47 .setTitle("Nucleus Privacy")
48 .setDescription(
49 "Nucleus is a bot that naturally needs to store data about servers.\n" +
50 "We are entirely [open source](https://github.com/ClicksMinutePer/Nucleus), so you can check exactly what we store, and how it works.\n\n" +
51 "If you are a server administrator, you can view the options page in the dropdown under this message.\n\n" +
52 "Any questions about Nucleus, how it works and data stored can be asked in [our server](https://discord.gg/bPaNnxe)."
53 )
54 .setEmoji("NUCLEUS.LOGO")
55 .setStatus("Danger")
pineafane23c4ec2022-07-27 21:56:27 +010056 )
Skyler Grey75ea9172022-08-06 10:22:23 +010057 .setTitle("Welcome")
58 .setDescription("General privacy information")
59 .setPageId(0),
60 new Embed()
61 .setEmbed(
62 new EmojiEmbed()
63 .setTitle("Scanners")
64 .setDescription(
pineafan3a02ea32022-08-11 21:35:04 +010065 "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 +010066 'This service\'s [privacy policy](https://unscan.co/policies) is public, and they "do not store or sell your data."'
67 )
68 .setEmoji("NUCLEUS.LOGO")
69 .setStatus("Danger")
70 )
71 .setTitle("Scanners")
72 .setDescription("About Unscan")
73 .setPageId(1),
74 new Embed()
75 .setEmbed(
76 new EmojiEmbed()
77 .setTitle("Link scanning and Transcripts")
78 .setDescription(
79 "**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" +
80 "**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" +
81 "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"
82 )
83 .setEmoji("NUCLEUS.LOGO")
84 .setStatus("Danger")
85 )
86 .setTitle("Link scanning and Transcripts")
Skyler Grey11236ba2022-08-08 21:13:33 +010087 .setDescription("Regarding Facebook and AMP filter types, and ticket transcripts")
Skyler Grey75ea9172022-08-06 10:22:23 +010088 .setPageId(2)
89 ].concat(
Skyler Grey11236ba2022-08-08 21:13:33 +010090 (interaction.member as Discord.GuildMember).permissions.has("ADMINISTRATOR")
Skyler Grey75ea9172022-08-06 10:22:23 +010091 ? [
92 new Embed()
93 .setEmbed(
94 new EmojiEmbed()
95 .setTitle("Options")
Skyler Grey11236ba2022-08-08 21:13:33 +010096 .setDescription("Below are buttons for controlling this servers privacy settings")
Skyler Grey75ea9172022-08-06 10:22:23 +010097 .setEmoji("NUCLEUS.LOGO")
98 .setStatus("Danger")
99 )
100 .setTitle("Options")
101 .setDescription("Options")
102 .setPageId(3)
103 .setComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400104 new ActionRowBuilder().addComponents([
105 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100106 .setLabel("Clear all data")
107 .setCustomId("clear-all-data")
TheCodedProf21c08592022-09-13 14:14:43 -0400108 .setStyle(ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +0100109 ])
110 ])
111 ]
112 : []
113 );
114 const m = await interaction.reply({
115 embeds: LoadingEmbed,
116 fetchReply: true,
117 ephemeral: true
118 });
pineafane23c4ec2022-07-27 21:56:27 +0100119 let page = 0;
120
121 let selectPaneOpen = false;
122 let nextFooter = null;
123
Skyler Greyad002172022-08-16 18:48:26 +0100124 let timedOut = false;
125 while (!timedOut) {
pineafan63fc5e22022-08-04 22:04:10 +0100126 let selectPane = [];
pineafane23c4ec2022-07-27 21:56:27 +0100127
128 if (selectPaneOpen) {
pineafan63fc5e22022-08-04 22:04:10 +0100129 const options = [];
Skyler Grey75ea9172022-08-06 10:22:23 +0100130 pages.forEach((embed) => {
131 options.push(
132 new SelectMenuOption({
133 label: embed.title,
134 value: embed.pageId.toString(),
135 description: embed.description || ""
136 })
137 );
pineafan63fc5e22022-08-04 22:04:10 +0100138 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100139 selectPane = [
TheCodedProf21c08592022-09-13 14:14:43 -0400140 new ActionRowBuilder().addComponents([
141 new Discord.SelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100142 .addOptions(options)
143 .setCustomId("page")
144 .setMaxValues(1)
145 .setPlaceholder("Choose a page...")
146 ])
147 ];
pineafane23c4ec2022-07-27 21:56:27 +0100148 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100149 const components = selectPane.concat([
TheCodedProf21c08592022-09-13 14:14:43 -0400150 new ActionRowBuilder().addComponents([
151 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100152 .setCustomId("left")
153 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400154 .setStyle(ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100155 .setDisabled(page === 0),
TheCodedProf21c08592022-09-13 14:14:43 -0400156 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100157 .setCustomId("select")
158 .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400159 .setStyle(selectPaneOpen ? ButtonStyle.Primary : ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100160 .setDisabled(false),
TheCodedProf21c08592022-09-13 14:14:43 -0400161 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100162 .setCustomId("right")
163 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400164 .setStyle(ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100165 .setDisabled(page === pages.length - 1)
166 ])
167 ]);
TheCodedProf21c08592022-09-13 14:14:43 -0400168 const em = new Discord.EmbedBuilder(pages[page].embed);
Skyler Grey11236ba2022-08-08 21:13:33 +0100169 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
Skyler Grey75ea9172022-08-06 10:22:23 +0100170 em.setFooter({ text: nextFooter ?? "" });
pineafane23c4ec2022-07-27 21:56:27 +0100171 await interaction.editReply({
172 embeds: [em],
173 components: components.concat(pages[page].components)
174 });
pineafan63fc5e22022-08-04 22:04:10 +0100175 let i;
pineafane23c4ec2022-07-27 21:56:27 +0100176 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100177 i = await m.awaitMessageComponent({ time: 300000 });
178 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100179 timedOut = true;
180 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100181 }
pineafan63fc5e22022-08-04 22:04:10 +0100182 nextFooter = null;
183 i.deferUpdate();
pineafane23c4ec2022-07-27 21:56:27 +0100184 if (i.component.customId === "left") {
185 if (page > 0) page--;
186 selectPaneOpen = false;
187 } else if (i.component.customId === "right") {
188 if (page < pages.length - 1) page++;
189 selectPaneOpen = false;
190 } else if (i.component.customId === "select") {
191 selectPaneOpen = !selectPaneOpen;
192 } else if (i.component.customId === "page") {
193 page = parseInt(i.values[0]);
194 selectPaneOpen = false;
195 } else if (i.component.customId === "clear-all-data") {
pineafan63fc5e22022-08-04 22:04:10 +0100196 const confirmation = await new confirmationMessage(interaction)
pineafane23c4ec2022-07-27 21:56:27 +0100197 .setEmoji("CONTROL.BLOCKCROSS")
198 .setTitle("Clear All Data")
199 .setDescription(
pineafan63fc5e22022-08-04 22:04:10 +0100200 "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 +0100201 "**This cannot be undone.**"
pineafane23c4ec2022-07-27 21:56:27 +0100202 )
203 .setColor("Danger")
pineafan63fc5e22022-08-04 22:04:10 +0100204 .send(true);
Skyler Grey75ea9172022-08-06 10:22:23 +0100205 if (confirmation.cancelled) {
206 break;
207 }
pineafane23c4ec2022-07-27 21:56:27 +0100208 if (confirmation.success) {
209 client.database.guilds.delete(interaction.guild.id);
210 client.database.history.delete(interaction.guild.id);
211 nextFooter = "All data cleared";
212 continue;
213 } else {
214 nextFooter = "No changes were made";
215 continue;
216 }
217 } else {
TheCodedProf21c08592022-09-13 14:14:43 -0400218 const em = new Discord.EmbedBuilder(pages[page].embed);
Skyler Grey11236ba2022-08-08 21:13:33 +0100219 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
Skyler Grey75ea9172022-08-06 10:22:23 +0100220 em.setFooter({ text: "Message closed" });
221 interaction.editReply({ embeds: [em], components: [] });
pineafan63fc5e22022-08-04 22:04:10 +0100222 return;
pineafane23c4ec2022-07-27 21:56:27 +0100223 }
pineafan73a7c4a2022-07-24 10:38:04 +0100224 }
TheCodedProf21c08592022-09-13 14:14:43 -0400225 const em = new Discord.EmbedBuilder(pages[page].embed);
Skyler Grey11236ba2022-08-08 21:13:33 +0100226 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
Skyler Grey75ea9172022-08-06 10:22:23 +0100227 em.setFooter({ text: "Message timed out" });
pineafane23c4ec2022-07-27 21:56:27 +0100228 await interaction.editReply({
229 embeds: [em],
230 components: []
231 });
pineafan63fc5e22022-08-04 22:04:10 +0100232};
pineafan4f164f32022-02-26 22:07:12 +0000233
PineaFan64486c42022-12-28 09:21:04 +0000234const check = (_interaction: CommandInteraction) => {
pineafan4f164f32022-02-26 22:07:12 +0000235 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100236};
pineafan4f164f32022-02-26 22:07:12 +0000237
238export { command };
239export { callback };
Skyler Grey75ea9172022-08-06 10:22:23 +0100240export { check };