From 50b99b4d73d8bf416a875c7ed81366face2afa03 Mon Sep 17 00:00:00 2001 From: LunaUrsa <1836049+LunaUrsa@users.noreply.github.com> Date: Wed, 21 Aug 2024 18:22:52 -0500 Subject: [PATCH 1/4] fix: Combos --- .vscode/settings.json | 3 ++- src/discord/commands/global/d.combo.ts | 3 ++- src/global/commands/g.combo.ts | 36 ++++++++++++++------------ 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index bc9f27267..8c85ae493 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,8 @@ { + "editor.defaultFormatter": "dbaeumer.vscode-eslint", "eslint.codeActionsOnSave.rules": null, "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" + "source.fixAll.eslint": "always" }, "eslint.validate": [ "javascript", diff --git a/src/discord/commands/global/d.combo.ts b/src/discord/commands/global/d.combo.ts index ddd234aba..d6a3ee6bd 100644 --- a/src/discord/commands/global/d.combo.ts +++ b/src/discord/commands/global/d.combo.ts @@ -26,12 +26,13 @@ export const dCombo: SlashCommand = { .setDescription('Set to "True" to show the response only to you')), async execute(interaction) { log.info(F, await commandContext(interaction)); - const ephemeral:boolean = (interaction.options.getBoolean('ephemeral') === true); + const ephemeral: boolean = (interaction.options.getBoolean('ephemeral') === true); await interaction.deferReply({ ephemeral }); const drugA = interaction.options.getString('first_drug', true); const drugB = interaction.options.getString('second_drug', true); const results = await combo(drugA, drugB); + // log.debug(F, `${JSON.stringify(results, null, 2)}`); if ((results as { err: boolean; diff --git a/src/global/commands/g.combo.ts b/src/global/commands/g.combo.ts index 259b40f2d..7f00e111f 100644 --- a/src/global/commands/g.combo.ts +++ b/src/global/commands/g.combo.ts @@ -57,7 +57,7 @@ export async function combo( let drugBName = drugBInput.toLowerCase(); // Because users can input whatever they want, we need to clean the input - function cleanDrugName(drugName:string):string { + function cleanDrugName(drugName: string): string { // These matches need to come first because otherwise "2x-b" woould be found in the drug DB but not have any interaction info if (/^do.$/i.test(drugName)) { return 'dox'; @@ -92,19 +92,6 @@ export async function combo( if (drug.combos && Object.keys(drug.combos).includes(drugName.toLowerCase())) { return drugName.toLowerCase(); } - - // Otherwise, check the categories - if (drug.categories) { - if (drug.categories.includes('benzodiazepine' as Category)) { - return 'benzodiazepines'; - } - if (drug.categories.includes('opioid' as Category)) { - return 'opioids'; - } - if (drug.categories.includes('ssri' as Category)) { - return 'ssris'; - } - } return drugName.toLowerCase(); } @@ -125,6 +112,23 @@ export async function combo( } } + if (Object.keys(drugData).includes(drugName.toLowerCase())) { + const drug = (drugData as DrugData)[drugName.toLowerCase()] as Drug; + + // Otherwise, check the categories + if (drug.categories) { + if (drug.categories.includes('benzodiazepine' as Category)) { + return 'benzodiazepines'; + } + if (drug.categories.includes('opioid' as Category)) { + return 'opioids'; + } + if (drug.categories.includes('ssri' as Category)) { + return 'ssris'; + } + } + } + return drugName; } @@ -157,8 +161,8 @@ export async function combo( // We use this to show the user all the drugs they can use const allDrugNames = Object.values(drugData as DrugData) - .filter((drug:Drug) => drug.aliases) // Filter drugs without aliases - .map((drug:Drug) => drug.aliases) // Get aliases + .filter((drug: Drug) => drug.aliases) // Filter drugs without aliases + .map((drug: Drug) => drug.aliases) // Get aliases .flat() as string[]; // Flatten array, define as string[] if (!drugAComboData) { From 1bff4b513ccb9394bbe5369fb0cc13530e67ac59 Mon Sep 17 00:00:00 2001 From: LunaUrsa <1836049+LunaUrsa@users.noreply.github.com> Date: Wed, 21 Aug 2024 18:36:50 -0500 Subject: [PATCH 2/4] fix: One more combo fix --- src/global/commands/g.combo.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/global/commands/g.combo.ts b/src/global/commands/g.combo.ts index 7f00e111f..d1d847321 100644 --- a/src/global/commands/g.combo.ts +++ b/src/global/commands/g.combo.ts @@ -92,7 +92,6 @@ export async function combo( if (drug.combos && Object.keys(drug.combos).includes(drugName.toLowerCase())) { return drugName.toLowerCase(); } - return drugName.toLowerCase(); } // If the drug is not in the drug database, check the combo database @@ -135,8 +134,8 @@ export async function combo( drugAName = cleanDrugName(drugAName); drugBName = cleanDrugName(drugBName); - // log.debug(F, `drugAName: ${drugAName}`); - // log.debug(F, `drugBName: ${drugBName}`); + log.debug(F, `drugAName: ${drugAName}`); + log.debug(F, `drugBName: ${drugBName}`); const drugANameString = drugAInput !== drugAName ? ` (converted to '${drugAName}')` : ''; const drugBNameString = drugBInput !== drugBName ? ` (converted to '${drugBName}')` : ''; From 96b167a09560718d788a35283237b46e75fe7348 Mon Sep 17 00:00:00 2001 From: LunaUrsa <1836049+LunaUrsa@users.noreply.github.com> Date: Sun, 25 Aug 2024 09:38:05 -0500 Subject: [PATCH 3/4] fix(moderate): note/report replies, actions not working on nonguild users (#841) * fix(moderate): note/report replies, actions not working on nonguild users * fix(moderate): re-add label length fix * fix: Use isNote and isReport --------- Co-authored-by: Shadow --- src/discord/commands/guild/d.moderate.ts | 77 +++++++++++++++--------- 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/src/discord/commands/guild/d.moderate.ts b/src/discord/commands/guild/d.moderate.ts index c7ac2c024..0aff4597b 100644 --- a/src/discord/commands/guild/d.moderate.ts +++ b/src/discord/commands/guild/d.moderate.ts @@ -839,43 +839,50 @@ export async function modResponse( create: { discord_id: userId }, update: {}, }); - - actionRow.addComponents( - modButtonNote(userId), - ); - let banVerb = 'ban'; - let userBan = {} as GuildBan; - try { - userBan = await interaction.guild.bans.fetch(userId); - } catch (err: unknown) { - // log.debug(F, `Error fetching ban: ${err}`); - } - if (userBan.guild) { + if (showModButtons) { actionRow.addComponents( - modButtonUnBan(userId), + modButtonNote(userId), ); - banVerb = 'un-ban'; - } else { + + let userBan = {} as GuildBan; + try { + userBan = await interaction.guild.bans.fetch(userId); + } catch (err: unknown) { + // log.debug(F, `Error fetching ban: ${err}`); + } + if (userBan.guild) { + actionRow.addComponents( + modButtonUnBan(userId), + ); + banVerb = 'un-ban'; + } else { + actionRow.addComponents( + modButtonBan(userId), + ); + } + actionRow.addComponents( - modButtonBan(userId), + modButtonInfo(userId), ); } - actionRow.addComponents( - modButtonInfo(userId), - ); - - if (isReport(command)) { + if (isReport(command) && showModButtons) { modEmbedObj.setDescription(stripIndents` User ID '${userId}' is not in the guild, but I can still Note or ${banVerb} them!`); } else { log.debug(F, '[modResponse] generating user info'); const modlogEmbed = await userInfoEmbed(actor, targetObj, targetData, command, showModButtons); log.debug(F, `modlogEmbed: ${JSON.stringify(modlogEmbed, null, 2)}`); - actionRow.setComponents([ - modButtonInfo(userId), - ]); + if (showModButtons) { + actionRow.setComponents([ + modButtonInfo(userId), + ]); + } else { + actionRow.setComponents([ + modButtonReport(userId), + ]); + } if (isBan(command)) { actionRow.addComponents( modButtonUnBan(userId), @@ -1699,7 +1706,7 @@ export async function moderate( > ${modalInt.fields.getTextInputValue('internalNote')} Message sent to user: - > ${modalInt.fields.getTextInputValue('description')}`, + > ${!isNote(command) && !isReport(command) ? modalInt.fields.getTextInputValue('description') : ''}`, inline: true, }, ); @@ -1721,7 +1728,7 @@ export async function moderate( .setDescription(desc) .setFooter(null); - if (command !== 'REPORT' && modThread) response.setDescription(`${response.data.description}\nYou can access their thread here: ${modThread}`); + if (!isReport(command) && modThread) response.setDescription(`${response.data.description}\nYou can access their thread here: ${modThread}`); log.debug(F, `Returning embed: ${JSON.stringify(response, null, 2)}`); return { embeds: [response] }; @@ -1952,6 +1959,20 @@ export async function modModal( return; } await i.deferReply({ ephemeral: true }); + try { + if (command === 'REPORT' || command === 'NOTE') { + await moderate(interaction, i); + const reportResponseEmbed = embedTemplate() + .setColor(command === 'REPORT' ? Colors.Yellow : Colors.Green) + .setTitle(command === 'REPORT' ? 'Your report was sent!' : 'Your note was added!') + .setDescription(command === 'REPORT' ? 'The moderators have received your report and will look into it. Thanks!' : `Your note was successfully added to ${target}'s thread.`); + await i.editReply({ + embeds: [reportResponseEmbed], + }); + } + } catch (err) { + log.info(F, `[modModal ModalSubmitInteraction]: ${err}`); + } // const internalNote = i.fields.getTextInputValue('internalNote'); // eslint-disable-line // // Only these commands actually have the description input, so only pull it if it exists @@ -2043,7 +2064,9 @@ export async function modModal( // log.error(F, `Error: ${err}`); } } - await i.editReply(await moderate(interaction, i)); + if (!isNote(command) && !isReport(command)) { + await i.editReply(await moderate(interaction, i)); + } }) .catch(async err => { // log.error(F, `Error: ${JSON.stringify(err as DiscordErrorData, null, 2)}`); From 320948d6e475da5aadc522f9531d1d6884548197 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Aug 2024 15:50:02 +0000 Subject: [PATCH 4/4] fix(ai): tos spam (#842) --- src/discord/commands/global/d.ai.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/discord/commands/global/d.ai.ts b/src/discord/commands/global/d.ai.ts index 961d7073c..0588f0399 100644 --- a/src/discord/commands/global/d.ai.ts +++ b/src/discord/commands/global/d.ai.ts @@ -1712,14 +1712,14 @@ async function agreeToTerms( embeds: [embedTemplate() .setTitle('🤖 Welcome to TripBot\'s AI Module! 🤖') .setDescription(` - Please agree to the following. Use \`/ai help\` for more more information. + Please agree to the following. Use \`/ai help\` for more information. ${termsOfService} `) .setFooter(null)], components: [ new ActionRowBuilder().addComponents( - buttonAiAgree.setCustomId(`AI~messageAgree~${messageData.id}`), + buttonAiAgree.setCustomId(`AI~messageAgree~${messageData.author.id}`), ), ], }; @@ -2397,11 +2397,12 @@ export async function aiButton( ):Promise { const buttonID = interaction.customId; log.debug(F, `buttonID: ${buttonID}`); - const [, buttonAction] = buttonID.split('~') as [ + const [, buttonAction, messageAuthorId] = buttonID.split('~') as [ null, 'help' | 'personas' | 'setup' | 'agree' | 'privacy' | 'link' | 'unlink' | 'messageAgree' | 'modify' | 'new' | - 'create' | 'delete' | 'deleteConfirm' | 'deleteHistory' | 'deleteHistoryConfirm']; + 'create' | 'delete' | 'deleteConfirm' | 'deleteHistory' | 'deleteHistoryConfirm', + string]; // eslint-disable-next-line sonarjs/no-small-switch switch (buttonAction) { @@ -2427,6 +2428,12 @@ export async function aiButton( }, }); + // const messageData = await interaction.message.fetchReference(); + + if (messageAuthorId !== interaction.user.id) { + log.debug(F, `${interaction.user.displayName} tried to accept the AI ToS using someone else's instance of the ToS.`); + return; + } await aiMessage(interaction.message); break; }