Implement premium features and GDPR compliance in bot and WebUI
- 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.
This commit is contained in:
77
apps/bot/src/modules/gdpr/commands.ts
Normal file
77
apps/bot/src/modules/gdpr/commands.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
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];
|
||||
Reference in New Issue
Block a user