- Added new models for premium tier configurations and assignments, enabling feature limits for free and premium users. - Introduced GDPR deletion logging and commands for user data management. - Enhanced logging configuration with retention days for audit logs. - Updated bot commands and job processing to include new premium and GDPR functionalities. - Improved localization with new keys for premium features and GDPR commands in both English and German. - Added UI components for managing premium settings and logging retention in the WebUI.
78 lines
2.4 KiB
TypeScript
78 lines
2.4 KiB
TypeScript
import { EmbedBuilder } from 'discord.js';
|
|
import { t, tf } from '@nexumi/shared';
|
|
import type { SlashCommand } from '../../types.js';
|
|
import { getGuildLocale } from '../../i18n.js';
|
|
import { env } from '../../env.js';
|
|
import { privacyCommandData, gdprCommandData } from './command-definitions.js';
|
|
import { deleteUserPersonalData } from './service.js';
|
|
|
|
const NEXUMI_COLOR = 0x6366f1;
|
|
|
|
function privacyUrl(): string {
|
|
const base = (env.WEBUI_URL ?? env.PUBLIC_BASE_URL).replace(/\/$/, '');
|
|
return `${base}/privacy`;
|
|
}
|
|
|
|
const privacyCommand: SlashCommand = {
|
|
data: privacyCommandData,
|
|
async execute(interaction, context) {
|
|
const locale = await getGuildLocale(context.prisma, interaction.guildId);
|
|
const embed = new EmbedBuilder()
|
|
.setTitle(t(locale, 'gdpr.privacy.title'))
|
|
.setColor(NEXUMI_COLOR)
|
|
.setDescription(
|
|
[
|
|
t(locale, 'gdpr.privacy.body'),
|
|
'',
|
|
tf(locale, 'gdpr.privacy.link', { url: privacyUrl() }),
|
|
t(locale, 'gdpr.privacy.deleteHint')
|
|
].join('\n')
|
|
);
|
|
await interaction.reply({ embeds: [embed], ephemeral: true });
|
|
}
|
|
};
|
|
|
|
const gdprCommand: SlashCommand = {
|
|
data: gdprCommandData,
|
|
async execute(interaction, context) {
|
|
const locale = await getGuildLocale(context.prisma, interaction.guildId);
|
|
const sub = interaction.options.getSubcommand(true);
|
|
if (sub !== 'delete') {
|
|
await interaction.reply({ content: t(locale, 'generic.unknownCommand'), ephemeral: true });
|
|
return;
|
|
}
|
|
|
|
const confirmed = interaction.options.getBoolean('confirm', true);
|
|
if (!confirmed) {
|
|
await interaction.reply({
|
|
content: t(locale, 'gdpr.delete.needConfirm'),
|
|
ephemeral: true
|
|
});
|
|
return;
|
|
}
|
|
|
|
await interaction.deferReply({ ephemeral: true });
|
|
const summary = await deleteUserPersonalData(
|
|
context.prisma,
|
|
interaction.user.id,
|
|
interaction.guildId
|
|
);
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setTitle(t(locale, 'gdpr.delete.doneTitle'))
|
|
.setColor(NEXUMI_COLOR)
|
|
.setDescription(
|
|
tf(locale, 'gdpr.delete.doneBody', {
|
|
warnings: summary.warnings,
|
|
levels: summary.memberLevels,
|
|
economy: summary.memberEconomies,
|
|
cases: summary.casesAnonymized
|
|
})
|
|
);
|
|
|
|
await interaction.editReply({ embeds: [embed] });
|
|
}
|
|
};
|
|
|
|
export const gdprCommands: SlashCommand[] = [privacyCommand, gdprCommand];
|