From dabfee619ac9a4bb24f5203ed4d6c09e34189c8a Mon Sep 17 00:00:00 2001 From: Kevinking500 Date: Thu, 28 May 2026 15:27:53 +0200 Subject: [PATCH 1/2] Hotfix for Staff Management & Ping Protection modules --- locales/en.json | 5 ++ .../commands/ping-protection.js | 2 +- .../events/interactionCreate.js | 28 ++++++- .../staff-management-system/commands/duty.js | 19 ++++- .../commands/staff-management.js | 4 - .../configs/reviews.json | 3 +- .../events/botReady.js | 17 +--- .../events/interactionCreate.js | 22 +++-- modules/staff-management-system/module.json | 2 +- .../staff-management.js | 83 +++++-------------- 10 files changed, 90 insertions(+), 95 deletions(-) diff --git a/locales/en.json b/locales/en.json index 24e2998..d360c78 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1013,8 +1013,11 @@ "field-wl-users": "Whitelisted Users", "list-none": "None are configured.", "modal-title": "Confirm data deletion for this user", + "fallback-modal-title": "Confirm data deletion", "modal-label": "Confirm data deletion by typing this phrase:", + "fallback-modal-label": "Confirm by typing this phrase:", "modal-phrase": "I understand that the data of this user will be deleted and that this action cannot be undone.", + "fallback-modal-phrase": "I confirm the data deletion of this user with risks.", "modal-failed": "The phrase you entered is incorrect. Data deletion cancelled.", "field-quick-history": "Quick history view (Last %w weeks)", "field-quick-desc": "Pings history amount: %p\nModeration actions amount: %m", @@ -1165,8 +1168,10 @@ "succ-ac-end": "✅ Activity check ended manually.", "err-gen-no-user": "❌ Could not find that user.", "del-conf-phrase": "I understand that this will delete the specified data for this user and it cannot be undone.", + "fallback-conf-phrase": "I confirm the data deletion with risks.", "mod-del-title": "Confirm Data Deletion", "mod-del-lbl": "Type confirmation phrase:", + "fallback-del-lbl": "Confirm with phrase:", "del-all-title": "Confirm total data deletion", "del-all-desc": "You are about to delete ALL data for this user. Reminder that this ***cannot be undone***. This is the last chance to back out. If you are sure, click the button below.\nThis action will automatically cancel in 30 seconds.", "btn-conf-del": "Confirm deletion", diff --git a/modules/ping-protection/commands/ping-protection.js b/modules/ping-protection/commands/ping-protection.js index 0d47c21..cbdf8e8 100644 --- a/modules/ping-protection/commands/ping-protection.js +++ b/modules/ping-protection/commands/ping-protection.js @@ -52,7 +52,7 @@ module.exports.subcommands = { await listHandler(interaction, 'whitelisted'); } } -}; +}}; // Handles list subcommands async function listHandler(interaction, type) { diff --git a/modules/ping-protection/events/interactionCreate.js b/modules/ping-protection/events/interactionCreate.js index f483e26..8f1e209 100644 --- a/modules/ping-protection/events/interactionCreate.js +++ b/modules/ping-protection/events/interactionCreate.js @@ -100,17 +100,33 @@ module.exports.run = async function (client, interaction) { }); } + // Checks to ensure modal content fits Discord limits + let modalTitle = localize('ping-protection', 'modal-title'); + if (modalTitle.length > 45) { + modalTitle = localize('ping-protection', 'fallback-modal-title'); + } + + let modalLabel = localize('ping-protection', 'modal-label'); + if (modalLabel.length > 45) { + modalLabel = localize('ping-protection', 'fallback-modal-label'); + } + + let confirmationPhrase = localize('ping-protection', 'modal-phrase'); + if (confirmationPhrase.length > 100) { + confirmationPhrase = localize('ping-protection', 'fallback-conf-phrase'); + } + const modal = new ModalBuilder() .setCustomId(`ping-protection_del-confirm_${targetId}_${selection}`) - .setTitle(localize('ping-protection', 'modal-title')); + .setTitle(modalTitle); modal.addComponents( new ActionRowBuilder().addComponents( new TextInputBuilder() .setCustomId('confirm') - .setLabel(localize('ping-protection', 'modal-label')) + .setLabel(modalLabel) .setStyle(TextInputStyle.Paragraph) - .setPlaceholder(localize('ping-protection', 'modal-phrase')) + .setPlaceholder(confirmationPhrase) .setRequired(true) ) ); @@ -130,7 +146,11 @@ module.exports.run = async function (client, interaction) { const targetId = parts[2]; const selection = parts.slice(3).join('_'); - const confirmPhrase = localize('ping-protection', 'modal-phrase'); + let confirmPhrase = localize('ping-protection', 'modal-phrase'); + if (confirmPhrase.length > 100) { + confirmPhrase = localize('ping-protection', 'fallback-conf-phrase'); + } + if (interaction.fields.getTextInputValue('confirm').trim() !== confirmPhrase) { return interaction.reply({ content: localize('ping-protection', 'modal-failed'), diff --git a/modules/staff-management-system/commands/duty.js b/modules/staff-management-system/commands/duty.js index 45e4a42..ce3aa26 100644 --- a/modules/staff-management-system/commands/duty.js +++ b/modules/staff-management-system/commands/duty.js @@ -1025,8 +1025,16 @@ async function handleDutyAdminVoidAll(client, interaction) { const permCheck = checkDutyAdminPermission(client, interaction); if (permCheck) return permCheck; + let confirmPhrase = localize('staff-management-system', 'del-conf-phrase'); + if (confirmPhrase.length > 100) { + confirmPhrase = localize('staff-management-system', 'fallback-conf-phrase'); + } + let delModalLabel = localize('staff-management-system', 'mod-del-lbl'); + if (delModalLabel.length > 45) { + delModalLabel = localize('staff-management-system', 'fallback-del-lbl'); + } + const targetUserId = interaction.customId.split('_')[2]; - const confirmPhrase = localize('staff-management-system', 'del-conf-phrase'); const modal = new ModalBuilder() .setCustomId(`duty-mgmt_admin-voidall-submit_${targetUserId}`) .setTitle(localize('staff-management-system', 'mod-v-all-title')); @@ -1035,8 +1043,8 @@ async function handleDutyAdminVoidAll(client, interaction) { new ActionRowBuilder().addComponents( new TextInputBuilder() .setCustomId('confirm') - .setLabel(localize('staff-management-system', 'mod-del-lbl')) - .setStyle(TextInputStyle.Short) + .setLabel(delModalLabel) + .setStyle(TextInputStyle.Paragraph) .setPlaceholder(confirmPhrase) .setRequired(true) ) @@ -1049,7 +1057,10 @@ async function handleDutyAdminVoidAllSubmit(client, interaction) { if (permCheck) return permCheck; const targetUserId = interaction.customId.split('_')[2]; - const confirmPhrase = localize('staff-management-system', 'del-conf-phrase'); + let confirmPhrase = localize('staff-management-system', 'del-conf-phrase'); + if (confirmPhrase.length > 100) { + confirmPhrase = localize('staff-management-system', 'fallback-conf-phrase'); + } if (interaction.fields.getTextInputValue('confirm').trim() !== confirmPhrase) { return interaction.reply({ diff --git a/modules/staff-management-system/commands/staff-management.js b/modules/staff-management-system/commands/staff-management.js index e667ee1..f064a46 100644 --- a/modules/staff-management-system/commands/staff-management.js +++ b/modules/staff-management-system/commands/staff-management.js @@ -138,10 +138,6 @@ async function handleProfileView(client, interaction, targetUser) { }; let embedTemplate = config.profileEmbedMessage; - if (typeof embedTemplate === 'string') { - try { embedTemplate = JSON.parse(embedTemplate); } catch (e) {} - } - let msgOpts = await embedTypeV2(embedTemplate, placeholders); if (!msgOpts) { diff --git a/modules/staff-management-system/configs/reviews.json b/modules/staff-management-system/configs/reviews.json index 6065550..a31bb24 100644 --- a/modules/staff-management-system/configs/reviews.json +++ b/modules/staff-management-system/configs/reviews.json @@ -21,7 +21,8 @@ "humanName": "Enable Reviews System", "description": "Enabling this unlocks the staff review system, allowing users to submit ratings with feedback for staff members.", "type": "boolean", - "default": true + "default": true, + "elementToggle": true }, { "name": "reviewLogChannel", diff --git a/modules/staff-management-system/events/botReady.js b/modules/staff-management-system/events/botReady.js index 6d2405a..09232f4 100644 --- a/modules/staff-management-system/events/botReady.js +++ b/modules/staff-management-system/events/botReady.js @@ -139,19 +139,10 @@ async function checkExpiredSuspensions(client, guild) { const profile = await StaffProfile.findByPk(susp.userId); try { - let rolesToRestore = []; - - if (profile?.suspendedRoles) { - try { - const parsed = JSON.parse(profile.suspendedRoles); - if (Array.isArray(parsed)) rolesToRestore = parsed; - } catch (e) { - client.logger.warn( - `[Staff Management] Failed to parse suspendedRoles for ${susp.userId}: ${e.message}` - ); - } - } - + let rolesToRestore = Array.isArray(profile?.suspendedRoles) + ? profile.suspendedRoles + : []; + if (member) { if (rolesToRestore.length > 0) { await member.roles.add(rolesToRestore).catch(e => { diff --git a/modules/staff-management-system/events/interactionCreate.js b/modules/staff-management-system/events/interactionCreate.js index 804f740..4808c4a 100644 --- a/modules/staff-management-system/events/interactionCreate.js +++ b/modules/staff-management-system/events/interactionCreate.js @@ -163,15 +163,24 @@ module.exports.run = async (client, interaction) => { return interaction.update(payload); } - const confirmPhrase = localize('staff-management-system', 'del-conf-phrase'); + let confirmPhrase = localize('staff-management-system', 'del-conf-phrase'); + if (confirmPhrase.length > 100) { + confirmPhrase = localize('staff-management-system', 'fallback-conf-phrase'); + } + let delModalLabel = localize('staff-management-system', 'mod-del-lbl'); + if (delModalLabel.length > 45) { + delModalLabel = localize('staff-management-system', 'fallback-del-lbl'); + } + const delModalTitle = localize('staff-management-system', 'mod-del-title'); + const modal = new ModalBuilder() .setCustomId(`staff-mgmt_del-confirm_${targetId}_${selection}`) - .setTitle(localize('staff-management-system', 'mod-del-title')); + .setTitle(delModalTitle); modal.addComponents( new ActionRowBuilder().addComponents( new TextInputBuilder() .setCustomId('confirm') - .setLabel(localize('staff-management-system', 'mod-del-lbl')) + .setLabel(delModalLabel) .setStyle(TextInputStyle.Paragraph) .setPlaceholder(confirmPhrase) .setRequired(true) @@ -195,7 +204,10 @@ module.exports.run = async (client, interaction) => { const targetId = parts[2]; const selection = parts.slice(3).join('_'); - const confirmPhrase = localize('staff-management-system', 'del-conf-phrase'); + let confirmPhrase = localize('staff-management-system', 'del-conf-phrase'); + if (confirmPhrase.length > 100) { + confirmPhrase = localize('staff-management-system', 'fallback-conf-phrase'); + } if (interaction.fields.getTextInputValue('confirm').trim() !== confirmPhrase) { return interaction.editReply({ @@ -524,7 +536,7 @@ module.exports.run = async (client, interaction) => { flags: MessageFlags.Ephemeral }); - const targetRoles = JSON.parse(activeCheck.targetRoles || '[]'); + const targetRoles = activeCheck.targetRoles || '[]'; const hasRole = targetRoles.length === 0 || interaction.member.roles.cache.some(r => targetRoles.includes(r.id)); if (!hasRole) return interaction.reply({ content: localize('staff-management-system', 'err-ac-not-req'), diff --git a/modules/staff-management-system/module.json b/modules/staff-management-system/module.json index 0d5c061..77348f9 100644 --- a/modules/staff-management-system/module.json +++ b/modules/staff-management-system/module.json @@ -21,7 +21,7 @@ "configs/activity-checks.json" ], "tags": [ - "moderation" + "administration" ], "humanReadableName": "Staff Management System", "description": "A powerful, highly customizable staff management system designed to track activity, moderate personnel, and maintain detailed staff records seamlessly." diff --git a/modules/staff-management-system/staff-management.js b/modules/staff-management-system/staff-management.js index 3538e88..9a1d592 100644 --- a/modules/staff-management-system/staff-management.js +++ b/modules/staff-management-system/staff-management.js @@ -119,17 +119,18 @@ async function issueInfraction(client, interaction, targetMember, type, reason, content: localize('staff-management-system', 'err-feat-disabled', {feature: 'Infractions'}) }); + const generalConfig = getConfig(client, 'configuration'); + const canInfract = checkStaffPermissions(interaction.member, generalConfig, 'supervisor'); + if (!canInfract) return interaction.editReply({ + content: localize('staff-management-system', 'err-gen-no-perm') + }); + if (targetMember.id === interaction.user.id) { return interaction.editReply({ content: localize('staff-management-system', 'err-self-infract') }); } - const canInfract = checkStaffPermissions(interaction.member, config, 'staff'); - if (!canInfract) return interaction.editReply({ - content: localize('staff-management-system', 'err-gen-no-perm') - }); - if (type.toLowerCase() === 'suspension') { return interaction.editReply({ content: localize('staff-management-system', 'err-use-susp') @@ -179,14 +180,6 @@ async function issueInfraction(client, interaction, targetMember, type, reason, const channel = await interaction.guild.channels.fetch(channelId).catch(() => null); if (channel) { let template = config.infractionMessage; - if (typeof template === 'string') { - try { - template = JSON.parse(template); - } catch (e) { - } - } else if (typeof template === 'object') { - template = JSON.parse(JSON.stringify(template)); - } if (template && template.embeds && !template._schema) template._schema = 'v3'; let msgOpts = await embedTypeV2(template, placeholders); @@ -205,15 +198,6 @@ async function issueInfraction(client, interaction, targetMember, type, reason, if (config.dmInfractedUser && config.infractionDmMessage) { let dmTemplate = config.infractionDmMessage; - if (typeof dmTemplate === 'string') { - try { - dmTemplate = JSON.parse(dmTemplate); - } catch (e) { - } - } else if (typeof dmTemplate === 'object') { - dmTemplate = JSON.parse(JSON.stringify(dmTemplate)); - } - if (dmTemplate && dmTemplate.embeds && !dmTemplate._schema) dmTemplate._schema = 'v3'; const dmOpts = await embedTypeV2(dmTemplate, placeholders); if (dmOpts?.content?.trim() === '') delete dmOpts.content; @@ -257,17 +241,17 @@ async function issueSuspension(client, interaction, targetMember, durationInput, }) }); + const canSuspend = checkStaffPermissions(interaction.member, config, 'supervisor'); + if (!canSuspend) return interaction.editReply({ + content: localize('staff-management-system', 'err-gen-no-perm') + }); + if (targetMember.id === interaction.user.id) { return interaction.editReply({ content: localize('staff-management-system', 'err-self-infract') }); } - const canSuspend = checkStaffPermissions(interaction.member, config, 'staff'); - if (!canSuspend) return interaction.editReply({ - content: localize('staff-management-system', 'err-gen-no-perm') - }); - const durationDays = parseDurationToDays(durationInput); if (!durationDays) return interaction.editReply({ @@ -292,7 +276,7 @@ async function issueSuspension(client, interaction, targetMember, durationInput, await client.models['staff-management-system']['StaffProfile'].upsert({ userId: targetMember.id, isSuspended: true, - suspendedRoles: JSON.stringify(rolesToRemove) + suspendedRoles: rolesToRemove }); if (config.suspensionRole) await targetMember.roles.add(config.suspensionRole).catch(() => {}); @@ -329,14 +313,6 @@ async function issueSuspension(client, interaction, targetMember, durationInput, const channel = await interaction.guild.channels.fetch(channelId).catch(() => null); if (channel) { let template = config.suspensionMessage; - if (typeof template === 'string') { - try { - template = JSON.parse(template); - } catch (e) { - } - } else if (typeof template === 'object') { - template = JSON.parse(JSON.stringify(template)); - } if (template && template.embeds && !template._schema) template._schema = 'v3'; let msgOpts = await embedTypeV2(template, placeholders); @@ -355,14 +331,6 @@ async function issueSuspension(client, interaction, targetMember, durationInput, if (config.dmInfractedUser && config.suspensionDmMessage) { let dmTemplate = config.suspensionDmMessage; - if (typeof dmTemplate === 'string') { - try { - dmTemplate = JSON.parse(dmTemplate); - } catch (e) { - } - } else if (typeof dmTemplate === 'object') { - dmTemplate = JSON.parse(JSON.stringify(dmTemplate)); - } if (dmTemplate && dmTemplate.embeds && !dmTemplate._schema) dmTemplate._schema = 'v3'; const dmOpts = await embedTypeV2(dmTemplate, placeholders); @@ -452,7 +420,7 @@ async function voidInfraction(client, interaction, reference) { if (member && profile && profile.isSuspended) { try { - const rolesToRestore = JSON.parse(profile.suspendedRoles || '[]'); + const rolesToRestore = profile.suspendedRoles || '[]'; if (rolesToRestore.length > 0) await member.roles.add(rolesToRestore); if (config.suspensionRole) await member.roles.remove(config.suspensionRole); await profile.update({ isSuspended: false, suspendedRoles: '[]' }); @@ -543,6 +511,12 @@ async function promoteUser(client, interaction, targetMember, newRole, reason) { content: localize('staff-management-system', 'err-feat-disabled', {feature: 'Promotions'}) }); + const generalConfig = getConfig(client, 'configuration'); + const canPromote = checkStaffPermissions(interaction.member, generalConfig, 'supervisor'); + if (!canPromote) return interaction.editReply({ + content: localize('staff-management-system', 'err-gen-no-perm') + }); + if (targetMember.id === interaction.user.id) { return interaction.editReply({ content: localize('staff-management-system', 'err-self-promo') @@ -602,13 +576,6 @@ async function promoteUser(client, interaction, targetMember, newRole, reason) { const channel = await interaction.guild.channels.fetch(targetChannelId).catch(() => null); if (channel) { let embedTemplate = config.promotionMessage; - if (typeof embedTemplate === 'string') { - try { - embedTemplate = JSON.parse(embedTemplate); - } - catch (e) {} } else if (typeof embedTemplate === 'object') { - embedTemplate = JSON.parse(JSON.stringify(embedTemplate)); - } if (embedTemplate && embedTemplate.embeds && !embedTemplate._schema) embedTemplate._schema = 'v3'; let msgOpts = await embedTypeV2(embedTemplate, placeholders); @@ -635,14 +602,6 @@ async function promoteUser(client, interaction, targetMember, newRole, reason) { if (config.dmPromotedUser && config.promotionDmMessage) { let dmTemplate = config.promotionDmMessage; - if (typeof dmTemplate === 'string') { - try { - dmTemplate = JSON.parse(dmTemplate); - } catch (e) { - } - } else if (typeof dmTemplate === 'object') { - dmTemplate = JSON.parse(JSON.stringify(dmTemplate)); - } if (dmTemplate && dmTemplate.embeds && !dmTemplate._schema) dmTemplate._schema = 'v3'; const dmOpts = await embedTypeV2(dmTemplate, placeholders); @@ -1452,7 +1411,7 @@ async function startActivityCheck(client, interactionOrChannel, isAutomated = fa messageId: checkMessage.id, channelId: targetChannel.id, endTime, - targetRoles: JSON.stringify(rolesToCheck), + targetRoles: rolesToCheck, status: 'ACTIVE', initiatorId: isAutomated ? null : interactionOrChannel.user.id, isAutomated @@ -1477,7 +1436,7 @@ async function endActivityCheckProcess(client, activeCheck) { const logChannel = guild.channels.cache.get(getSafeChannelId(config.logChannel) || getSafeChannelId(getConfig(client, 'configuration')?.generalLogChannel)); if (!logChannel) return; - const targetRoles = JSON.parse(activeCheck.targetRoles || '[]'); + const targetRoles = activeCheck.targetRoles || '[]'; const ActivityCheckResponse = client.models['staff-management-system']['ActivityCheckResponse']; const responses = await ActivityCheckResponse.findAll({ where: { activityCheckId: activeCheck.id }, From 4580aa63f72c48b5bb143508d54da24e2fbe4ae3 Mon Sep 17 00:00:00 2001 From: Kevinking500 Date: Thu, 28 May 2026 16:46:53 +0200 Subject: [PATCH 2/2] Minor changes --- .../ping-protection/commands/ping-protection.js | 9 ++------- .../ping-protection/events/interactionCreate.js | 4 ++-- modules/staff-management-system/events/botReady.js | 14 +++++++++++--- .../events/interactionCreate.js | 2 +- .../staff-management-system/staff-management.js | 13 +++++++------ 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/modules/ping-protection/commands/ping-protection.js b/modules/ping-protection/commands/ping-protection.js index cbdf8e8..5a0f8e3 100644 --- a/modules/ping-protection/commands/ping-protection.js +++ b/modules/ping-protection/commands/ping-protection.js @@ -44,13 +44,8 @@ module.exports.subcommands = { 'protected': async function (interaction) { await listHandler(interaction, 'protected'); }, - 'list': { - 'protected': async function (interaction) { - await listHandler(interaction, 'protected'); - }, - 'whitelisted': async function (interaction) { - await listHandler(interaction, 'whitelisted'); - } + 'whitelisted': async function (interaction) { + await listHandler(interaction, 'whitelisted'); } }}; diff --git a/modules/ping-protection/events/interactionCreate.js b/modules/ping-protection/events/interactionCreate.js index 8f1e209..b181e73 100644 --- a/modules/ping-protection/events/interactionCreate.js +++ b/modules/ping-protection/events/interactionCreate.js @@ -113,7 +113,7 @@ module.exports.run = async function (client, interaction) { let confirmationPhrase = localize('ping-protection', 'modal-phrase'); if (confirmationPhrase.length > 100) { - confirmationPhrase = localize('ping-protection', 'fallback-conf-phrase'); + confirmationPhrase = localize('ping-protection', 'fallback-modal-phrase'); } const modal = new ModalBuilder() @@ -148,7 +148,7 @@ module.exports.run = async function (client, interaction) { let confirmPhrase = localize('ping-protection', 'modal-phrase'); if (confirmPhrase.length > 100) { - confirmPhrase = localize('ping-protection', 'fallback-conf-phrase'); + confirmPhrase = localize('ping-protection', 'fallback-modal-phrase'); } if (interaction.fields.getTextInputValue('confirm').trim() !== confirmPhrase) { diff --git a/modules/staff-management-system/events/botReady.js b/modules/staff-management-system/events/botReady.js index 09232f4..787be60 100644 --- a/modules/staff-management-system/events/botReady.js +++ b/modules/staff-management-system/events/botReady.js @@ -139,9 +139,17 @@ async function checkExpiredSuspensions(client, guild) { const profile = await StaffProfile.findByPk(susp.userId); try { - let rolesToRestore = Array.isArray(profile?.suspendedRoles) - ? profile.suspendedRoles - : []; + let rolesToRestore = []; + if (profile?.suspendedRoles) { + try { + const parsed = JSON.parse(profile.suspendedRoles); + if (Array.isArray(parsed)) rolesToRestore = parsed; + } catch (e) { + client.logger.warn( + `[Staff Management] Failed to parse suspendedRoles for ${susp.userId}: ${e.message}` + ); + } + } if (member) { if (rolesToRestore.length > 0) { diff --git a/modules/staff-management-system/events/interactionCreate.js b/modules/staff-management-system/events/interactionCreate.js index 4808c4a..cea2316 100644 --- a/modules/staff-management-system/events/interactionCreate.js +++ b/modules/staff-management-system/events/interactionCreate.js @@ -536,7 +536,7 @@ module.exports.run = async (client, interaction) => { flags: MessageFlags.Ephemeral }); - const targetRoles = activeCheck.targetRoles || '[]'; + const targetRoles = JSON.parse(activeCheck.targetRoles || '[]'); const hasRole = targetRoles.length === 0 || interaction.member.roles.cache.some(r => targetRoles.includes(r.id)); if (!hasRole) return interaction.reply({ content: localize('staff-management-system', 'err-ac-not-req'), diff --git a/modules/staff-management-system/staff-management.js b/modules/staff-management-system/staff-management.js index 9a1d592..9e79df6 100644 --- a/modules/staff-management-system/staff-management.js +++ b/modules/staff-management-system/staff-management.js @@ -241,7 +241,8 @@ async function issueSuspension(client, interaction, targetMember, durationInput, }) }); - const canSuspend = checkStaffPermissions(interaction.member, config, 'supervisor'); + const generalConfig = getConfig(client, 'configuration'); + const canSuspend = checkStaffPermissions(interaction.member, generalConfig, 'supervisor'); if (!canSuspend) return interaction.editReply({ content: localize('staff-management-system', 'err-gen-no-perm') }); @@ -276,7 +277,7 @@ async function issueSuspension(client, interaction, targetMember, durationInput, await client.models['staff-management-system']['StaffProfile'].upsert({ userId: targetMember.id, isSuspended: true, - suspendedRoles: rolesToRemove + suspendedRoles: JSON.stringify(rolesToRemove) }); if (config.suspensionRole) await targetMember.roles.add(config.suspensionRole).catch(() => {}); @@ -420,10 +421,10 @@ async function voidInfraction(client, interaction, reference) { if (member && profile && profile.isSuspended) { try { - const rolesToRestore = profile.suspendedRoles || '[]'; + const rolesToRestore = JSON.parse(profile.suspendedRoles || '[]'); if (rolesToRestore.length > 0) await member.roles.add(rolesToRestore); if (config.suspensionRole) await member.roles.remove(config.suspensionRole); - await profile.update({ isSuspended: false, suspendedRoles: '[]' }); + await profile.update({ isSuspended: false, suspendedRoles: JSON.stringify([]) }); } catch (e) { return interaction.editReply({ content: localize('staff-management-system', 'succ-void-fail', {caseId: record.caseId}) @@ -1411,7 +1412,7 @@ async function startActivityCheck(client, interactionOrChannel, isAutomated = fa messageId: checkMessage.id, channelId: targetChannel.id, endTime, - targetRoles: rolesToCheck, + targetRoles: JSON.stringify(rolesToCheck), status: 'ACTIVE', initiatorId: isAutomated ? null : interactionOrChannel.user.id, isAutomated @@ -1436,7 +1437,7 @@ async function endActivityCheckProcess(client, activeCheck) { const logChannel = guild.channels.cache.get(getSafeChannelId(config.logChannel) || getSafeChannelId(getConfig(client, 'configuration')?.generalLogChannel)); if (!logChannel) return; - const targetRoles = activeCheck.targetRoles || '[]'; + const targetRoles = JSON.parse(activeCheck.targetRoles || '[]'); const ActivityCheckResponse = client.models['staff-management-system']['ActivityCheckResponse']; const responses = await ActivityCheckResponse.findAll({ where: { activityCheckId: activeCheck.id },