Adds a regression suite for #3843 so the leak cannot return silently. The
client had no test runner, so this introduces Vitest, which reuses the
existing Vite resolution and the `@/` alias rather than needing a separate
transform pipeline. jsdom is required because the logger reads
window.location and navigator.userAgent.
The tests drive the exported `logger` rather than the private redaction
helpers, so they cover the wiring as well as the logic. That distinction
matters here: the first attempt at this fix redacted the JSON branch but
left the debug branch printing raw objects, a gap that testing the helper
in isolation would not have caught. Each case runs at both error and debug
level for the same reason.
Covered: the reported login payload, credentials carried on an AxiosError
(config.data and the Authorization header), non-JSON request bodies,
passwords on class instances, key-matching variants, and circular payloads.
One asserts non-sensitive context survives, so redaction cannot regress
into blanket suppression.
Verified by reverting the fix: 16 of 23 tests fail against the original
behaviour, including a pre-existing crash on circular payloads.
The form only enforced the length cap, so CSS with an external url() or @import
passed client validation and was rejected by the server. Add the same tokenizer
based check with the same error message so it is caught inline before submit.
## Changes
- Bump axios from ^1.7.x to ^1.15.2 in both client/ and server/
## Benefits
- Patches CVE-2025-62718 (NO_PROXY hostname normalization SSRF)
- Patches CVE-2026-40175 (cloud metadata exfiltration via header injection)
- Minor bump within existing ^1.x semver range; no API changes
Capture the five recurring code-review patterns from the recent PR series
(#3591–#3596) as enforceable rules so they don't have to be raised again
in review.
## Conventions
- Prefer MUI native props over `sx` (e.g. color={...}, mt={...}, width={...}).
- Use the full theme path for colors: theme.palette.text.secondary, never
the "text.secondary" shorthand string. The shorthand is invisible to
grep, which makes future audits and refactors miss callsites.
- No hardcoded numeric or string literals — use LAYOUT, typographyLevels,
theme.shape.borderRadius, theme.palette tokens.
- Use useTheme() inside components; don't import { theme } from
@/Utils/Theme/Theme (factory output, not a live mode-aware instance).
- Pair runtime tuples with derived types so they can't drift.
## Files
- docs/frontend-conventions.md — long-form doc with before/after examples
drawn from the actual review fixes, plus a pre-PR checklist.
- CLAUDE.md — short summary in the Code Conventions section pointing to
the doc, so it's loaded into agent context at session start.
## ESLint enforcement
- client/.eslintrc.cjs — four no-restricted-syntax selectors for each rule:
- color="…" / bgcolor="…" / borderColor="…" with a dotted shorthand value
- sx={{ key: ... }} where key has a native equivalent, only on hoistable
components (Box, Stack, Typography, Grid, Container, Paper, Card*,
Divider, Link, Chip) — Dialog/Drawer/Menu etc. only accept sx.
- import { theme } from "@/Utils/Theme/Theme"
- Typography fontSize={13} (the body default — drop the prop).
- TypeScript files are now actually parsed: added @typescript-eslint/parser
and @typescript-eslint/eslint-plugin and a TS override that extends the
React plugin configs. Several @typescript-eslint/recommended rules
disabled to avoid noise on the existing codebase.
- client/package.json — lint script now covers .ts/.tsx; new lint-strict
script for CI use once the codebase is conformant; --max-warnings 0
removed from `lint` so existing-code warnings don't block the workflow.
## Surface
Running `npm run lint` after this change reports ~280 warnings against
the existing codebase, almost all from rule #1 (sx-vs-native). These are
intentionally warnings, not errors — they surface the work without
blocking. Each warning links to the rule number in the conventions doc
so the reasoning is one click away.
Replace the flag + 2-letter code in the language selector with each language's native name (English, Deutsch, 日本語, ...) and drop the unused flag-icons dependency.
The client version shown on the Settings page was hardcoded as a
literal in vite.config.ts, while client/package.json sat at the
placeholder "0.0.0". Bumping the displayed version required editing
two unrelated places, and stale Docker client images would keep
showing the old number after upgrades.
This change makes client/package.json the single source of truth
and reads it at build time. Bumps client/package.json from 0.0.0
to 3.6.1 to preserve current behaviour.
Closes#3271
Replace custom SVG icons and @mui/icons-material with lucide-react for consistent,
lightweight icon management across the application.
## Changes
- Add lucide-react package and remove @mui/icons-material
- Create theme-aware Icon wrapper component with color resolution
- Create iconMap.js for legacy icon name mappings
- Migrate 64 components to use new Icon component
- Remove 74 unused SVG files from assets/icons/
## Benefits
- Consistent icon API across the application
- Smaller bundle size with tree-shakeable imports
- Theme-aware color support via MUI theme paths
- Simpler maintenance with single icon library