diff --git a/components/phishing/url-list.tsx b/components/phishing/url-list.tsx new file mode 100644 index 0000000..f7f4002 --- /dev/null +++ b/components/phishing/url-list.tsx @@ -0,0 +1,50 @@ +'use client'; + +/* UrlList — inert, copy-only rendering of URLs extracted from a reported + * phishing/spam email (REVIEW-03, D-09). + * + * D-09 is a deliberately STRICTER-than-sanitization posture: extracted URLs + * are attacker-controlled content and must never be rendered as anything + * clickable. There is no anchor tag with a navigation attribute, no + * ``, and no navigating `onClick` anywhere in this file — the only + * affordance is copy-to-clipboard via an icon-only button. Do not "improve" + * this by adding a real link. */ + +import { Copy } from 'lucide-react'; +import { toast } from 'sonner'; +import { Button } from '@/components/ui/button'; + +interface UrlListProps { + urls: string[]; +} + +export function UrlList({ urls }: UrlListProps) { + if (urls.length === 0) { + return ( +

No URLs found in this message.

+ ); + } + + async function handleCopy(url: string) { + await navigator.clipboard.writeText(url); + toast.success('Copied'); + } + + return ( + + ); +} diff --git a/components/ui/tooltip.tsx b/components/ui/tooltip.tsx new file mode 100644 index 0000000..ec65c1e --- /dev/null +++ b/components/ui/tooltip.tsx @@ -0,0 +1,57 @@ +"use client" + +import * as React from "react" +import { Tooltip as TooltipPrimitive } from "radix-ui" + +import { cn } from "@/lib/utils" + +function TooltipProvider({ + delayDuration = 0, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function Tooltip({ + ...props +}: React.ComponentProps) { + return +} + +function TooltipTrigger({ + ...props +}: React.ComponentProps) { + return +} + +function TooltipContent({ + className, + sideOffset = 0, + children, + ...props +}: React.ComponentProps) { + return ( + + + {children} + + + + ) +} + +export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }