refactor(frontend): extract SectionLabel + EmptyState + adminStyles shared #132

Merged
lekss361 merged 3 commits from refactor/frontend-ui-shared-129 into main 2026-05-14 20:55:38 +00:00

3 commits

Author SHA1 Message Date
lekss361
96fc007609 docs(adminStyles): JSDoc warning про divergent local overrides
Per bot review #132 non-blocking minor — задокументировать почему
leads/page.tsx и BulkGeoPanel.tsx имеют local overrides, чтобы будущий
читатель не «унифицировал» обратно по ошибке.

Refs: #129, #132
2026-05-14 23:54:35 +03:00
lekss361
d33023d7d6 refactor(frontend): SectionLabel + EmptyState + adminStyles shared (fixup)
Per audit batch #127 P2 hygiene (issue #129). Previous commit лошил
файлы из-за pre-commit (видимо). Fixup-коммит с actual diff:

## New shared modules (3)

- frontend/src/components/ui/SectionLabel.tsx
- frontend/src/components/ui/EmptyState.tsx
- frontend/src/lib/adminStyles.ts

## Replacements

- SectionLabel: 12 inline usages → import (Overview/Land/Market/Environment Tab)
- EmptyState: 3 inline usages → import (Land/Market/Environment)
- adminStyles: 5 admin pages import cardStyle/labelStyle/inputStyle/th/td
- BulkGeoPanel: cardStyle only (preserves local labelStyle для span)
- leads/page.tsx: cardStyle с marginTop extend; th/td/inputStyle local (divergent)

## Visual regression: ZERO

All px/colors/CSS properties copied verbatim. Files с divergent values left local.

## Checks

- ruff (no files)
- prettier
- tsc + lint clean (per agent run)

Closes #129
Refs: #127
2026-05-14 23:49:15 +03:00
lekss361
6186804eb8 fix(docs): block javascript: URLs in renderMarkdown href (XSS guard)
Per audit batch #127 P2 security minor (issue #130).

## Risk

`renderMarkdown` substituted `[text](url)` → `<a href="...url...">` verbatim
без URL validation. Edge case: `[click](javascript:alert(1))` →
`<a href="javascript:alert(1)">click</a>` execute'нется при click.

Currently low risk (markdown source = build-time fs.readFileSync из
public/docs/, checked into repo), но защита-в-глубину: если когда-либо
markdown source станет user-supplied, vuln materialize.

## Fix

`frontend/src/app/docs/b2b-channels/renderMarkdown.ts`:

1. New `safeUrl(url)` function — allowlist `https://`, `http://`, `/`, `#`,
   `mailto:`. Everything else → `"#"`.
2. Link regex replacement switched from backreference string to callback
   so URL passes через `safeUrl` ДО injection в href.
3. URL unescape → safeUrl → re-escape (HTML escape applied per-line).

## Test cases verified

- `[ok](https://example.com)` → href=`https://example.com` 
- `[ok](/local)` → href=`/local` 
- `[ok](#anchor)` → href=`#anchor` 
- `[ok](mailto:foo@bar.com)` → href=`mailto:foo@bar.com` 
- `[bad](javascript:alert(1))` → href=`#` 
- `[bad](data:text/html,...)` → href=`#` 
- `[bad](vbscript:msgbox(1))` → href=`#` 

## Checks

- tsc: 0 errors
- lint: 0 warnings
- No existing `__tests__/renderMarkdown` to break

## Vault

`fixes/Bug_RenderMarkdown_JavascriptUrl_May14.md` — created.

Closes #130
2026-05-14 23:34:03 +03:00