716947228e
WebView2 (Windows) sieht im User-Agent aus wie Edge, WebKitGTK (Linux) wie Safari — im Postfach war eine Client-Meldung von einer Browser-Meldung nicht zu unterscheiden. Neuer reiner Helfer origin.ts leitet aus vier optionalen DTO-Feldern (Desktop-App) bzw. dem User-Agent (Browser) ein Betreff-Kuerzel und eine Zeile "Herkunft: ..." ab; rein informativ, laengenbegrenzt, nichts wird gespeichert (T-GZA-01). Browser-Pfad ist damit Ende-zu-Ende fertig. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016g2npLxzH5gZpg8s2S6vKh
115 lines
3.5 KiB
TypeScript
115 lines
3.5 KiB
TypeScript
import { Expose, Transform } from 'class-transformer';
|
|
import {
|
|
ArrayMaxSize,
|
|
IsArray,
|
|
IsIn,
|
|
IsOptional,
|
|
IsString,
|
|
MaxLength,
|
|
} from 'class-validator';
|
|
|
|
/**
|
|
* Rumpf von `POST /bug-reports` (quick-260914-m97, Fehler-melden-Knopf).
|
|
*
|
|
* Die Felder kommen als `multipart/form-data` (das Bild liegt als Datei
|
|
* `screenshot` daneben, siehe Controller) — multer liefert deshalb alle
|
|
* Textfelder als Strings. Ein EINZELNES wiederholtes Feld `errors` kommt
|
|
* als String, mehrere als Array, keines als undefined (append-field,
|
|
* gemessen zur Planungszeit); ohne die Normalisierung unten wuerde
|
|
* `@IsArray()` bei genau einer Fehlermeldung scheitern.
|
|
*
|
|
* Mandant und Benutzer stehen BEWUSST NICHT in diesem DTO (T-M97-06): der
|
|
* Dienst nimmt beides ausschliesslich aus dem Sitzungsnachweis
|
|
* (`@CurrentUser()`), und `whitelist: true` der globalen ValidationPipe
|
|
* entfernt jedes Fremdfeld, das ein Client hier trotzdem mitschickt.
|
|
*
|
|
* Vier weitere Felder (`clientKind`, `clientOs`, `clientVersion`,
|
|
* `clientCommit`) kommen seit quick-260918-gza vom Web-Client dazu — im
|
|
* Browser als `clientKind=browser` mit leeren uebrigen Feldern, in der
|
|
* Desktop-App aus dem Cookie `tessera_desktop_client`. Sie sind optional,
|
|
* damit aeltere Web-Baue weiterhin gueltig senden (der Dienst faellt ohne
|
|
* sie auf `browser` zurueck); `whitelist: true` verlangt ihre Deklaration
|
|
* hier, sonst wuerde die Pipe sie stillschweigend entfernen. Sie dienen
|
|
* ausschliesslich der Anzeige in der Mail und sind laengenbegrenzt
|
|
* (T-GZA-01) — siehe `origin.ts`.
|
|
*/
|
|
export class BugReportDto {
|
|
/** Freitext „Was ist passiert?“ — optional, hoechstens 4000 Zeichen. */
|
|
@IsOptional()
|
|
@IsString()
|
|
@MaxLength(4000)
|
|
description?: string;
|
|
|
|
/** Pfad plus Suchteil der Seite, ohne Host. */
|
|
@IsString()
|
|
@MaxLength(2000)
|
|
page!: string;
|
|
|
|
@IsString()
|
|
@MaxLength(100)
|
|
webVersion!: string;
|
|
|
|
@IsString()
|
|
@MaxLength(20)
|
|
webChannel!: string;
|
|
|
|
/** Kurzer Commit-Hash; Leerstring ist erlaubt (lokaler Bau ohne Stempel). */
|
|
@IsString()
|
|
@MaxLength(64)
|
|
webCommit!: string;
|
|
|
|
@IsString()
|
|
@MaxLength(1000)
|
|
userAgent!: string;
|
|
|
|
/** `<Breite>x<Hoehe>` des Browserfensters. */
|
|
@IsString()
|
|
@MaxLength(50)
|
|
viewport!: string;
|
|
|
|
/** ISO-Zeitstempel des Browsers zum Sendezeitpunkt. */
|
|
@IsString()
|
|
@MaxLength(50)
|
|
clientTime!: string;
|
|
|
|
/**
|
|
* Die letzten Fehlermeldungen aus dem Browser-Ringpuffer, je
|
|
* `[<ISO>] <Art>: <Meldung>`. `@Expose()` sorgt dafuer, dass die
|
|
* Normalisierung auch laeuft, wenn das Feld im Rumpf GANZ fehlt
|
|
* (class-transformer ruft `@Transform` sonst nur fuer vorhandene
|
|
* Schluessel auf — gemessen: ohne `@Expose()` scheitert `@IsArray()`).
|
|
*/
|
|
@Expose()
|
|
@Transform(({ value }) =>
|
|
value === undefined || value === null ? [] : Array.isArray(value) ? value : [value],
|
|
)
|
|
@IsArray()
|
|
@ArrayMaxSize(30)
|
|
@IsString({ each: true })
|
|
@MaxLength(1000, { each: true })
|
|
errors!: string[];
|
|
|
|
/** `desktop` oder `browser` — vom Web-Client gesetzt, siehe Kopfkommentar. */
|
|
@IsOptional()
|
|
@IsIn(['desktop', 'browser'])
|
|
clientKind?: 'desktop' | 'browser';
|
|
|
|
/** Betriebssystem der Desktop-App (`windows`, `linux`, `macos`, …), unbeglaubigt. */
|
|
@IsOptional()
|
|
@IsString()
|
|
@MaxLength(20)
|
|
clientOs?: string;
|
|
|
|
/** Version der Desktop-App (`CARGO_PKG_VERSION`), unbeglaubigt. */
|
|
@IsOptional()
|
|
@IsString()
|
|
@MaxLength(40)
|
|
clientVersion?: string;
|
|
|
|
/** Commit-Stempel der Desktop-App (`APP_COMMIT`), darf leer sein. */
|
|
@IsOptional()
|
|
@IsString()
|
|
@MaxLength(40)
|
|
clientCommit?: string;
|
|
}
|