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:
@@ -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 } });
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user