Impressum, Datenschutzerklärung und DSGVO-Löschfunktion
- /impressum (§ 5 DDG) und /datenschutz als öffentliche Seiten im Brand-Look; Betreiber-Angaben (Name, Anschrift, E-Mail, Zusatz) liegen als Settings und sind bewusst Owner-only — Team-Mitglieder mit settings-Scope kommen an die private Anschrift nicht heran - Die Datenschutzerklärung beschreibt die tatsächliche Verarbeitung dieser Instanz: Server-Logs, Session-Cookies (einwilligungsfrei nach § 25 Abs. 2 TDDDG, kein Tracking), Discord-Login, Level, Wünsche, Geburtstage, Playtester/Alpha-Keys, Bewerbungen, Tickets/Modmail, Erinnerungen, Moderation und Audit-Log - DSGVO Art. 17: DELETE /api/profile löscht XP, Geburtstag, Playtester-Eintrag, Abstimmungen, Erinnerungen, Rollen-Sicherung, Giveaway-Teilnahmen und gibt den Alpha-Key wieder frei; Button im Profil unter „Meine Daten", Löschung landet im Audit-Log - Footer verlinkt beide Rechtstexte, neues GET /api/legal (öffentlich) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+29
-2
@@ -14,7 +14,7 @@ import {
|
||||
saveWebAdmin, webAdminScopes, listWebAdmins, deleteWebAdmin,
|
||||
saveTemplate, listTemplates, deleteTemplate,
|
||||
getLevelRow, isPlaytester, saveWish, toggleWishVote, myWishVotes,
|
||||
logAudit, listAudit, playerHistory,
|
||||
logAudit, listAudit, playerHistory, deleteUserData,
|
||||
} from '../db.js';
|
||||
import { lastResults, GAME_ICONS } from '../bot/server-monitor.js';
|
||||
import { publishAppForm, unpublishAppForm, MAX_QUESTIONS } from '../bot/app-forms.js';
|
||||
@@ -23,7 +23,7 @@ import { publishRoleMenu, unpublishRoleMenu, MAX_ENTRIES } from '../bot/role-men
|
||||
import { computeNextRun } from './scheduled-posts.js';
|
||||
import { config } from '../config.js';
|
||||
import { removeDevlog } from '../bot/devlog-archive.js';
|
||||
import { commitChannelId, devlogChannelId, releaseChannelId, devlogPingRoleId, publicUrl, roadmapRepo, brandColor, brandFooter, brandName, giteaApiToken, votingChannelId, discordGuildId, discordInviteUrl } from '../runtime-settings.js';
|
||||
import { commitChannelId, devlogChannelId, releaseChannelId, devlogPingRoleId, publicUrl, roadmapRepo, brandColor, brandFooter, brandName, giteaApiToken, votingChannelId, discordGuildId, discordInviteUrl, legalInfo } from '../runtime-settings.js';
|
||||
import { xpForLevel } from '../bot/levels.js';
|
||||
import { getMilestones } from '../gitea-api.js';
|
||||
import { getSessionUser, isAdmin, isGuildMember } from './auth.js';
|
||||
@@ -353,6 +353,10 @@ ${rssItems}
|
||||
discord_invite_url: getSetting('discord_invite_url') ?? '',
|
||||
birthday_channel_id: getSetting('birthday_channel_id') ?? '',
|
||||
birthday_role_id: getSetting('birthday_role_id') ?? '',
|
||||
legal_name: getSetting('legal_name') ?? '',
|
||||
legal_address: getSetting('legal_address') ?? '',
|
||||
legal_email: getSetting('legal_email') ?? '',
|
||||
legal_extra: getSetting('legal_extra') ?? '',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -390,6 +394,7 @@ ${rssItems}
|
||||
for (const key of [
|
||||
'gitea_api_token', 'twitch_client_id', 'twitch_client_secret',
|
||||
'discord_guild_id', 'bot_name', 'bot_description', 'public_url', 'gitea_url',
|
||||
'legal_name', 'legal_address', 'legal_email', 'legal_extra',
|
||||
]) delete body[key];
|
||||
}
|
||||
|
||||
@@ -545,6 +550,10 @@ ${rssItems}
|
||||
setSetting(key, String(body[key]).trim());
|
||||
}
|
||||
}
|
||||
// Impressums-Angaben (Owner-only, oben bereits gefiltert)
|
||||
for (const key of ['legal_name', 'legal_address', 'legal_email', 'legal_extra']) {
|
||||
if (body[key] !== undefined) setSetting(key, String(body[key]).trim().slice(0, 500));
|
||||
}
|
||||
// URLs: müssen mit http(s) beginnen
|
||||
for (const key of ['public_url', 'gitea_url']) {
|
||||
if (body[key] === undefined) continue;
|
||||
@@ -1111,6 +1120,24 @@ ${rssItems}
|
||||
|
||||
app.get('/api/invite', async () => ({ invite: discordInviteUrl() }));
|
||||
|
||||
// Betreiber-Angaben für Impressum/Datenschutz — öffentlich (müssen es sein)
|
||||
app.get('/api/legal', async () => ({
|
||||
legal: legalInfo(),
|
||||
brand: brandName(),
|
||||
publicUrl: publicUrl(),
|
||||
guildConfigured: Boolean(discordGuildId()),
|
||||
}));
|
||||
|
||||
// DSGVO Art. 17: eigene Daten löschen
|
||||
app.delete('/api/profile', async (request, reply) => {
|
||||
if (await requireMember(request, reply)) return;
|
||||
const user = getSessionUser(request);
|
||||
const deleted = deleteUserData(user.id);
|
||||
request.log.info(`Datenlöschung für ${user.id}: ${JSON.stringify(deleted)}`);
|
||||
logAudit(user, 'daten gelöscht (dsgvo)', user.username);
|
||||
return { ok: true, deleted };
|
||||
});
|
||||
|
||||
app.get('/api/profile', async (request, reply) => {
|
||||
if (await requireMember(request, reply)) return;
|
||||
const user = getSessionUser(request);
|
||||
|
||||
Reference in New Issue
Block a user