ux: clean security warnings modal and overlays

This commit is contained in:
LC mac
2026-01-31 01:58:32 +08:00
parent 2a7ac1cce0
commit a607cd74cf
2 changed files with 81 additions and 90 deletions

View File

@@ -1,81 +1,66 @@
import { useState } from 'react';
export const SecurityWarnings = () => {
const [isExpanded, setIsExpanded] = useState(false);
import React from 'react';
export const SecurityWarnings: React.FC = () => {
return (
<div className="fixed top-4 left-4 z-50 max-w-sm">
<div className="bg-yellow-50 border-2 border-yellow-400 rounded-lg shadow-lg">
<div className="space-y-3">
<Warning
icon="🧵"
title="JavaScript Strings are Immutable"
description="Strings cannot be overwritten in memory. Copies persist until garbage collection runs (timing unpredictable)."
/>
{/* Header */}
<div
className="px-4 py-3 cursor-pointer flex items-center justify-between hover:bg-yellow-100 transition-colors rounded-t-lg"
onClick={() => setIsExpanded(!isExpanded)}
>
<div className="flex items-center gap-2">
<span className="text-lg"></span>
<span className="font-semibold text-sm text-yellow-900">Security Limitations</span>
</div>
<span className="text-yellow-600 text-sm">{isExpanded ? '▼' : '▶'}</span>
</div>
<Warning
icon="🗑️"
title="No Guaranteed Memory Wiping"
description="JavaScript has no secure memory clearing. Sensitive data may linger in RAM until GC or browser restart."
/>
{/* Expanded Content */}
{isExpanded && (
<div className="px-4 py-3 border-t border-yellow-300 space-y-3 max-h-96 overflow-y-auto">
<Warning
icon="📋"
title="Clipboard Exposure"
description="Copied data is accessible to other tabs/apps. Browser extensions can read clipboard contents."
/>
<Warning
icon="🧵"
title="JavaScript Strings are Immutable"
description="Strings cannot be overwritten in memory. Copies persist until garbage collection runs (timing unpredictable)."
/>
<Warning
icon="💾"
title="Browser Storage Persistence"
description="localStorage survives browser restart. sessionStorage survives page refresh. Both readable by any script on this domain."
/>
<Warning
icon="🗑️"
title="No Guaranteed Memory Wiping"
description="JavaScript has no secure memory clearing. Sensitive data may linger in RAM until GC or browser restart."
/>
<Warning
icon="🔍"
title="DevTools Access"
description="All app state, memory, and storage visible in browser DevTools. Never use on untrusted devices."
/>
<Warning
icon="📋"
title="Clipboard Exposure"
description="Copied data is accessible to other tabs/apps. Browser extensions can read clipboard contents."
/>
<Warning
icon="🌐"
title="Network Risks (When Online)"
description="If hosted online: DNS, HTTPS, CDN, and browser can see usage patterns. Use offline/local for maximum security."
/>
<Warning
icon="💾"
title="Browser Storage Persistence"
description="localStorage survives browser restart. sessionStorage survives page refresh. Both readable by any script on this domain."
/>
<Warning
icon="🔍"
title="DevTools Access"
description="All app state, memory, and storage visible in browser DevTools. Never use on untrusted devices."
/>
<Warning
icon="🌐"
title="Network Risks (When Online)"
description="If hosted online: DNS, HTTPS, CDN, and browser can see usage patterns. Use offline/local for maximum security."
/>
<div className="pt-2 border-t border-yellow-300 text-xs text-yellow-800">
<strong>Recommendation:</strong> Use this tool on a dedicated offline device.
Clear browser data after each use. Never use on shared/public computers.
</div>
</div>
)}
<div className="pt-3 border-t border-slate-600 text-xs text-slate-400">
<strong className="text-slate-300">Recommendation:</strong>{' '}
Use this tool on a dedicated offline device. Clear browser data after each use. Never use on shared/public computers.
</div>
</div>
);
};
const Warning = ({ icon, title, description }: { icon: string; title: string; description: string }) => (
<div className="flex gap-2 text-xs">
<span className="text-base flex-shrink-0">{icon}</span>
const Warning = ({
icon,
title,
description,
}: {
icon: string;
title: string;
description: string;
}) => (
<div className="flex gap-2 text-sm">
<span className="text-lg flex-shrink-0">{icon}</span>
<div>
<div className="font-semibold text-yellow-900 mb-0.5">{title}</div>
<div className="text-yellow-800 leading-relaxed">{description}</div>
<div className="font-semibold text-slate-200 mb-1">{title}</div>
<div className="text-slate-400 leading-relaxed">{description}</div>
</div>
</div>
);