0ac4beaaa8
- Add requireAuth() to admin-permissions.ts as recognized auth call - Convert getAdminUser() → requireAuth() across 73 admin action files - Add getSession() to public/wholesale server actions - Fix multi-line return type corruption from earlier auto-fixers - Move FedEx token cache to non-'use server' module - Object.freeze module-level constants: PRICE_KEYS, EMPTY_MOBILE_DASHBOARD, EMPTY_PAY_PERIOD, LOCALE_CART_SUBJECT, WELCOME_EMAILS - Update Stripe API version 2026-05-27 → 2026-06-24 - Fix wholesale employee portal: getEmployeeSessionAction + EmployeePortalClient - Fix 51 TypeScript errors (return type corruption, missing imports)
41 lines
1.2 KiB
TypeScript
41 lines
1.2 KiB
TypeScript
"use client";
|
|
|
|
import DOMPurify from "dompurify";
|
|
|
|
/**
|
|
* Render a sanitized HTML string as React children. Use this anywhere
|
|
* `dangerouslySetInnerHTML` would otherwise be the only option (e.g.
|
|
* email preview bodies, template bodies, etc.).
|
|
*
|
|
* DOMPurify is configured with a strict default profile plus a small
|
|
* allow-list for the elements commonly used in our email templates
|
|
* (inline styles, tables, images with http(s) sources). Custom config
|
|
* can be passed via the second argument if needed.
|
|
*/
|
|
export function SafeHtml({
|
|
html,
|
|
className,
|
|
...rest
|
|
}: {
|
|
html: string;
|
|
className?: string;
|
|
} & React.HTMLAttributes<HTMLDivElement>) {
|
|
const clean = DOMPurify.sanitize(html, {
|
|
USE_PROFILES: { html: true },
|
|
ALLOWED_ATTR: [
|
|
"href", "target", "rel", "src", "alt", "title", "style", "class",
|
|
"id", "name", "colspan", "rowspan", "width", "height", "align",
|
|
"valign", "bgcolor", "color", "border", "cellpadding", "cellspacing",
|
|
"role", "aria-label", "aria-hidden",
|
|
],
|
|
});
|
|
return (
|
|
<div
|
|
className={className}
|
|
// The sanitizer above guarantees the result is safe to inject.
|
|
dangerouslySetInnerHTML={{ __html: clean }}
|
|
{...rest}
|
|
/>
|
|
);
|
|
}
|