Fix clipboard copy on HTTP — use execCommand fallback

navigator.clipboard requires HTTPS (secure context). Fall back to
textarea + execCommand('copy') for the View in CARD button.
This commit is contained in:
Jordan Ramos
2026-06-09 12:35:24 -06:00
parent f3319ee1f5
commit f8b420f4e4
2 changed files with 21 additions and 2 deletions

View File

@@ -155,7 +155,16 @@ export default function CardActionModal({ isOpen, onClose, item, initialAction,
{item?.host_id && ( {item?.host_id && (
<button <button
onClick={() => { onClick={() => {
navigator.clipboard.writeText(String(item.host_id)); try {
const ta = document.createElement('textarea');
ta.value = String(item.host_id);
ta.style.position = 'fixed';
ta.style.opacity = '0';
document.body.appendChild(ta);
ta.select();
document.execCommand('copy');
document.body.removeChild(ta);
} catch (_) { /* best effort */ }
window.open('https://card.charter.com/ipn-search', '_blank'); window.open('https://card.charter.com/ipn-search', '_blank');
}} }}
title={`Copy Host ID ${item.host_id} and open CARD`} title={`Copy Host ID ${item.host_id} and open CARD`}

View File

@@ -12,6 +12,7 @@ import ReactDOM from 'react-dom';
import { Loader, AlertCircle, ExternalLink, Copy } from 'lucide-react'; import { Loader, AlertCircle, ExternalLink, Copy } from 'lucide-react';
// ⚠️ CONVENTION: Use relative API path fallback, not absolute URL. Should be: process.env.REACT_APP_API_BASE || '/api' // ⚠️ CONVENTION: Use relative API path fallback, not absolute URL. Should be: process.env.REACT_APP_API_BASE || '/api'
// Other components in this project use fetch() with relative paths and credentials: 'include'
const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api'; const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api';
const TOOLTIP_GAP = 8; const TOOLTIP_GAP = 8;
@@ -328,7 +329,16 @@ function TooltipBody({ data, loading, error, anchorRect, ip, hostId, onAction, o
{hostId && ( {hostId && (
<button <button
onClick={() => { onClick={() => {
navigator.clipboard.writeText(String(hostId)); try {
const ta = document.createElement('textarea');
ta.value = String(hostId);
ta.style.position = 'fixed';
ta.style.opacity = '0';
document.body.appendChild(ta);
ta.select();
document.execCommand('copy');
document.body.removeChild(ta);
} catch (_) { /* best effort */ }
window.open('https://card.charter.com/ipn-search', '_blank'); window.open('https://card.charter.com/ipn-search', '_blank');
}} }}
title={`Copy Host ID ${hostId} and open CARD`} title={`Copy Host ID ${hostId} and open CARD`}