fix(tradein): санитизация brand.logo_url + валидация brand-цветов (#766) (#791)
All checks were successful
Deploy Trade-In / build-frontend (push) Successful in 1m32s
Deploy Trade-In / deploy (push) Successful in 56s
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / test (push) Has been skipped
Deploy Trade-In / build-backend (push) Has been skipped
All checks were successful
Deploy Trade-In / build-frontend (push) Successful in 1m32s
Deploy Trade-In / deploy (push) Successful in 56s
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / test (push) Has been skipped
Deploy Trade-In / build-backend (push) Has been skipped
Co-authored-by: bot-frontend <bot-frontend@gendsgn.local> Co-committed-by: bot-frontend <bot-frontend@gendsgn.local>
This commit is contained in:
parent
3653f020b6
commit
b175ea4225
2 changed files with 22 additions and 4 deletions
|
|
@ -58,8 +58,15 @@ export default function TradeInPage() {
|
|||
useEffect(() => {
|
||||
const root = document.documentElement;
|
||||
if (!brand) return;
|
||||
root.style.setProperty("--accent", brand.primary_color); // зелёный (бренд)
|
||||
root.style.setProperty("--accent-2", brand.accent_color); // циан (акцент)
|
||||
// Бренд-цвета идут в CSS custom-property без доверия (#766: подменённый бренд
|
||||
// → CSS-инъекция). Применяем только валидный hex / rgb()/hsl(); иначе дефолт.
|
||||
const COLOR_RE = /^#[0-9a-fA-F]{3,8}$|^(rgb|hsl)a?\([\d.,%\s/]+\)$/;
|
||||
if (COLOR_RE.test(brand.primary_color)) {
|
||||
root.style.setProperty("--accent", brand.primary_color); // зелёный (бренд)
|
||||
}
|
||||
if (COLOR_RE.test(brand.accent_color)) {
|
||||
root.style.setProperty("--accent-2", brand.accent_color); // циан (акцент)
|
||||
}
|
||||
root.classList.add("brand-active");
|
||||
return () => {
|
||||
root.style.removeProperty("--accent");
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
import { UserMenu } from "@/components/auth/UserMenu";
|
||||
import { API_BASE_URL, HTTPError } from "@/lib/api";
|
||||
import { isPathAllowed } from "@/lib/isPathAllowed";
|
||||
import { safeUrl } from "@/lib/safeUrl";
|
||||
import { useBrand } from "@/lib/useBrand";
|
||||
import { useMe } from "@/lib/useMe";
|
||||
|
||||
|
|
@ -94,9 +95,19 @@ export function Topbar({ active }: TopbarProps) {
|
|||
<header className="topbar">
|
||||
<div className="topbar-inner">
|
||||
<div className="brand">
|
||||
{brand?.logo_url ? (
|
||||
{brand ? (
|
||||
<>
|
||||
<img src={brand.logo_url} alt={brand.name} className="brand-logo" />
|
||||
{/* logo_url из бренд-конфига → safeUrl (блок javascript:/data: схем, #766).
|
||||
Невалидный URL → fallback на TI-марку, без broken/опасного img. */}
|
||||
{safeUrl(brand.logo_url) ? (
|
||||
<img
|
||||
src={safeUrl(brand.logo_url) as string}
|
||||
alt={brand.name}
|
||||
className="brand-logo"
|
||||
/>
|
||||
) : (
|
||||
<span className="brand-mark">TI</span>
|
||||
)}
|
||||
<span className="brand-product">{brand.name}</span>
|
||||
</>
|
||||
) : (
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue