From 5a4a7860343da6640cda7e032502a617df7f85f2 Mon Sep 17 00:00:00 2001 From: waychan23 Date: Thu, 4 Dec 2025 18:18:52 +0800 Subject: [PATCH] fix: copying api key to the clipboard fails when the page is accessed via insecure connection(http without tls). Fixed by adding a fallback method for copy text to clipboard. --- surfsense_web/hooks/use-api-key.ts | 57 +++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/surfsense_web/hooks/use-api-key.ts b/surfsense_web/hooks/use-api-key.ts index 6f955adc3..678307ba9 100644 --- a/surfsense_web/hooks/use-api-key.ts +++ b/surfsense_web/hooks/use-api-key.ts @@ -33,17 +33,58 @@ export function useApiKey(): UseApiKeyReturn { return () => clearTimeout(timer); }, []); + const fallbackCopyTextToClipboard = (text: string) => { + const textArea = document.createElement("textarea"); + textArea.value = text; + + // Avoid scrolling to bottom + textArea.style.top = "0"; + textArea.style.left = "0"; + textArea.style.position = "fixed"; + textArea.style.opacity = "0"; + + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + + try { + const successful = document.execCommand('copy'); + document.body.removeChild(textArea); + + if (successful) { + setCopied(true); + toast.success("API key copied to clipboard"); + + setTimeout(() => { + setCopied(false); + }, 2000); + } else { + toast.error("Failed to copy API key"); + } + } catch (err) { + console.error("Fallback: Oops, unable to copy", err); + document.body.removeChild(textArea); + toast.error("Failed to copy API key"); + } + }; + const copyToClipboard = useCallback(async () => { if (!apiKey) return; try { - await navigator.clipboard.writeText(apiKey); - setCopied(true); - toast.success("API key copied to clipboard"); - - setTimeout(() => { - setCopied(false); - }, 2000); + if (navigator.clipboard && window.isSecureContext) { + // Use Clipboard API if available and in secure context + await navigator.clipboard.writeText(apiKey); + setCopied(true); + toast.success("API key copied to clipboard"); + + setTimeout(() => { + setCopied(false); + }, 2000); + } else { + // Fallback for non-secure contexts or browsers without clipboard API + fallbackCopyTextToClipboard(apiKey); + } } catch (err) { console.error("Failed to copy:", err); toast.error("Failed to copy API key"); @@ -56,4 +97,4 @@ export function useApiKey(): UseApiKeyReturn { copied, copyToClipboard, }; -} +} \ No newline at end of file