diff --git a/frontend-modern/src/components/Settings/APITokenManager.tsx b/frontend-modern/src/components/Settings/APITokenManager.tsx index ca3d991ba..2c66bc1ef 100644 --- a/frontend-modern/src/components/Settings/APITokenManager.tsx +++ b/frontend-modern/src/components/Settings/APITokenManager.tsx @@ -1,5 +1,6 @@ import { createSignal, Show, onMount } from 'solid-js'; import { SystemAPI, APITokenStatus } from '@/api/system'; +import { copyToClipboard } from '@/utils/clipboard'; export function APITokenManager() { const [tokenStatus, setTokenStatus] = createSignal(null); @@ -64,38 +65,15 @@ export function APITokenManager() { } }; - const copyToClipboard = async () => { - if (currentToken()) { - try { - // Check if clipboard API is available (requires HTTPS in most browsers) - if (navigator.clipboard && navigator.clipboard.writeText) { - await navigator.clipboard.writeText(currentToken()!); - setCopied(true); - setTimeout(() => setCopied(false), 2000); - } else { - // Fallback for HTTP or unsupported browsers - const textArea = document.createElement('textarea'); - textArea.value = currentToken()!; - textArea.style.position = 'fixed'; - textArea.style.left = '-999999px'; - textArea.style.top = '-999999px'; - document.body.appendChild(textArea); - textArea.select(); - try { - document.execCommand('copy'); - setCopied(true); - setTimeout(() => setCopied(false), 2000); - } catch (err) { - console.error('Failed to copy:', err); - setError('Failed to copy - please select and copy manually'); - } finally { - document.body.removeChild(textArea); - } - } - } catch (err) { - console.error('Failed to copy:', err); - setError('Failed to copy - please select and copy manually'); - } + const handleCopy = async () => { + if (!currentToken()) return; + + const success = await copyToClipboard(currentToken()!); + if (success) { + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } else { + setError('Failed to copy - please select and copy manually'); } }; @@ -153,15 +131,18 @@ export function APITokenManager() { onClick={(e) => e.currentTarget.select()} /> -

- Use this token for API authentication. Keep it secure! -

+
+

Use this token for API authentication:

+ + curl -H "X-API-Token: {currentToken()}" {window.location.origin}/api/health + +
diff --git a/frontend-modern/src/components/Settings/CurrentAPIToken.tsx b/frontend-modern/src/components/Settings/CurrentAPIToken.tsx index b66bdab2e..4c586b9d9 100644 --- a/frontend-modern/src/components/Settings/CurrentAPIToken.tsx +++ b/frontend-modern/src/components/Settings/CurrentAPIToken.tsx @@ -1,5 +1,6 @@ import { Component, createSignal, Show } from 'solid-js'; import { showError } from '@/utils/toast'; +import { copyToClipboard } from '@/utils/clipboard'; export const CurrentAPIToken: Component = () => { const [lastGeneratedToken, setLastGeneratedToken] = createSignal(null); @@ -15,14 +16,14 @@ export const CurrentAPIToken: Component = () => { setLastGeneratedToken(storedToken); } - const copyToClipboard = async () => { + const handleCopy = async () => { if (!lastGeneratedToken()) return; - try { - await navigator.clipboard.writeText(lastGeneratedToken()!); + const success = await copyToClipboard(lastGeneratedToken()!); + if (success) { setCopied(true); setTimeout(() => setCopied(false), 2000); - } catch (err) { + } else { showError('Failed to copy to clipboard'); } }; @@ -70,7 +71,7 @@ export const CurrentAPIToken: Component = () => { {lastGeneratedToken()} - + + {/* Content */} +
+
+ + + +
@@ -1515,12 +1549,26 @@ const Settings: Component = () => { {/* API Token - Show current token when auth is enabled */} -
-

API Token

-

- Your API token for automation and integrations -

- +
+ {/* Header */} +
+
+
+ + + +
+
+

API Token

+

For automation and integrations

+
+
+
+ + {/* Content */} +
+ +