Umlaute statt Umschreibungen

Oberflaeche, Fehlermeldungen und Kommentare schrieben durchgehend ae, oe, ue
und ss. Dafuer gab es keinen Grund - die Anwendung ist deutschsprachig und
laeuft durchgehend in UTF-8.

Betroffen waren 55 Dateien, darunter alle sichtbaren Texte: Guthaben-Zaehler,
Import, Nutzerverwaltung, Passwortwechsel und die Zwei-Faktor-Einrichtung.

Der Name einer Migration bleibt im README-Beispiel bewusst bei ASCII, weil
daraus ein Verzeichnisname wird.
This commit is contained in:
2026-09-18 16:57:39 +02:00
parent b9364151b0
commit 724f68644b
49 changed files with 256 additions and 254 deletions
+1 -1
View File
@@ -160,7 +160,7 @@ export async function adminRoutes(app: FastifyInstance): Promise<void> {
app.delete('/api/admin/users/:id', async (request) => {
const { id } = parseWith(idParam, request.params);
if (id === request.user?.id) {
throw conflict('SELF_DELETE', 'Der eigene Account kann nicht geloescht werden');
throw conflict('SELF_DELETE', 'Der eigene Account kann nicht gelöscht werden');
}
const target = await prisma.user.findUnique({ where: { id } });
+3 -3
View File
@@ -77,7 +77,7 @@ export async function authRoutes(app: FastifyInstance): Promise<void> {
sameSite: 'lax',
expires: expiresAt,
});
// Muss fuer das Double-Submit-Verfahren lesbar sein.
// Muss für das Double-Submit-Verfahren lesbar sein.
reply.setCookie(CSRF_COOKIE, csrfTokenFor(token), {
path: '/',
httpOnly: false,
@@ -91,7 +91,7 @@ export async function authRoutes(app: FastifyInstance): Promise<void> {
const body = parseWith(loginSchema, request.body);
const user = await prisma.user.findUnique({ where: { username: body.username } });
// Auch ohne Treffer einmal hashen, damit die Antwortzeit nichts verraet.
// Auch ohne Treffer einmal hashen, damit die Antwortzeit nichts verrät.
const digest = user?.passwordHash ?? '$argon2id$v=19$m=19456,t=2,p=1$aaaaaaaaaaaaaaaa$aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
const passwordOk = await verifyPassword(digest, body.password);
@@ -250,7 +250,7 @@ export async function authRoutes(app: FastifyInstance): Promise<void> {
app.post('/api/account/totp/setup', { preHandler: requireAuth }, async (request) => {
const secret = generateSecret();
// Erst nach bestaetigtem Code aktivieren, sonst sperrt sich der Nutzer aus.
// Erst nach bestätigtem Code aktivieren, sonst sperrt sich der Nutzer aus.
await prisma.user.update({
where: { id: request.user!.id },
data: { totpSecret: secret, totpEnabled: false },
+1 -1
View File
@@ -87,7 +87,7 @@ export async function characterRoutes(app: FastifyInstance): Promise<void> {
app.post('/api/characters/:id/revert', { preHandler: requireEditor }, async (request) => {
const { id } = parseWith(idParam, request.params);
const body = parseWith(
z.object({ reason: z.string().trim().min(1, 'Eine Begruendung ist Pflicht').max(500) }),
z.object({ reason: z.string().trim().min(1, 'Eine Begründung ist Pflicht').max(500) }),
request.body,
);
return revertCharacter(id, body.reason, contextOf(request));
+2 -2
View File
@@ -42,7 +42,7 @@ export async function creditRoutes(app: FastifyInstance): Promise<void> {
z.object({
kind: z.nativeEnum(CreditKind),
amount: z.number().int().refine((v) => v !== 0, 'Betrag darf nicht 0 sein'),
note: z.string().trim().min(1, 'Eine Begruendung ist Pflicht').max(500),
note: z.string().trim().min(1, 'Eine Begründung ist Pflicht').max(500),
}),
request.body,
);
@@ -52,7 +52,7 @@ export async function creditRoutes(app: FastifyInstance): Promise<void> {
app.post('/api/credits/:id/reverse', { preHandler: requireEditor }, async (request) => {
const { id } = parseWith(idParam, request.params);
const body = parseWith(
z.object({ reason: z.string().trim().min(1, 'Eine Begruendung ist Pflicht').max(500) }),
z.object({ reason: z.string().trim().min(1, 'Eine Begründung ist Pflicht').max(500) }),
request.body,
);
return reverseGroup(id, body.reason, contextOf(request));
+1 -1
View File
@@ -3,7 +3,7 @@ import { z } from 'zod';
import { badRequest, unauthorized } from '../errors.js';
import type { ActionContext } from '../services/audit.js';
// z.output statt z.input: nur so zaehlen .default()-Werte als gesetzt.
// z.output statt z.input: nur so zählen .default()-Werte als gesetzt.
export function parseWith<S extends z.ZodTypeAny>(schema: S, input: unknown): z.output<S> {
const result = schema.safeParse(input);
if (!result.success) {
+3 -3
View File
@@ -14,16 +14,16 @@ import {
import { contextOf, idParam, parseWith } from './helpers.js';
const mappingBody = z.object({
playerKey: z.string().min(1, 'Spalte fuer die Spieler-Kennung fehlt'),
playerKey: z.string().min(1, 'Spalte für die Spieler-Kennung fehlt'),
playerName: z.string().optional(),
product: z.string().min(1, 'Spalte fuer den Produktnamen fehlt'),
product: z.string().min(1, 'Spalte für den Produktnamen fehlt'),
orderId: z.string().optional(),
purchasedAt: z.string().optional(),
createMissingPlayers: z.boolean().default(false),
});
export async function importRoutes(app: FastifyInstance): Promise<void> {
// Der Import veraendert Guthaben in grosser Zahl und bleibt deshalb Admins vorbehalten.
// Der Import verändert Guthaben in großer Zahl und bleibt deshalb Admins vorbehalten.
app.post('/api/imports', { preHandler: requireAdmin }, async (request, reply) => {
const file = await request.file();
if (!file) throw badRequest('NO_FILE', 'Es wurde keine Datei hochgeladen');
+1 -1
View File
@@ -15,7 +15,7 @@ import { contextOf, idParam, parseWith } from './helpers.js';
export async function scraperRoutes(app: FastifyInstance): Promise<void> {
/**
* Gleicht die Profile bereits erfasster Spieler ab. Bewusst nur die
* bekannten: der Abgleich soll vorhandene Konten ergaenzen, nicht fremde
* bekannten: der Abgleich soll vorhandene Konten ergänzen, nicht fremde
* Profile auf Vorrat einsammeln.
*/
app.post('/api/scrape/run', { preHandler: requireAdmin }, async (request) => {