From f49e290ea5f85ade05a0183d2d6eb04b914feb6f Mon Sep 17 00:00:00 2001 From: Pulse Monitor Date: Thu, 14 Aug 2025 08:00:45 +0000 Subject: [PATCH] feat: add API token retrieval in current session - Store API tokens in sessionStorage during security setup - Add CurrentAPIToken component to display tokens from current session - Show token section in Settings when authentication is enabled - Tokens can only be retrieved during the session they were created - After logout/restart, tokens cannot be recovered (stored as SHA3-256 hash) This addresses user feedback about making API tokens retrievable after initial setup, similar to other applications, while maintaining security. --- .../components/Settings/CurrentAPIToken.tsx | 128 ++++++++++++++++++ .../Settings/QuickSecuritySetup.tsx | 5 + .../src/components/Settings/Settings.tsx | 13 +- 3 files changed, 139 insertions(+), 7 deletions(-) create mode 100644 frontend-modern/src/components/Settings/CurrentAPIToken.tsx diff --git a/frontend-modern/src/components/Settings/CurrentAPIToken.tsx b/frontend-modern/src/components/Settings/CurrentAPIToken.tsx new file mode 100644 index 000000000..b66bdab2e --- /dev/null +++ b/frontend-modern/src/components/Settings/CurrentAPIToken.tsx @@ -0,0 +1,128 @@ +import { Component, createSignal, Show } from 'solid-js'; +import { showError } from '@/utils/toast'; + +export const CurrentAPIToken: Component = () => { + const [lastGeneratedToken, setLastGeneratedToken] = createSignal(null); + const [showToken, setShowToken] = createSignal(false); + const [copied, setCopied] = createSignal(false); + + // Store the last generated token in sessionStorage so it persists during the session + const sessionKey = 'pulse_last_api_token'; + + // Check if we have a token from this session + const storedToken = sessionStorage.getItem(sessionKey); + if (storedToken) { + setLastGeneratedToken(storedToken); + } + + const copyToClipboard = async () => { + if (!lastGeneratedToken()) return; + + try { + await navigator.clipboard.writeText(lastGeneratedToken()!); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } catch (err) { + showError('Failed to copy to clipboard'); + } + }; + + return ( +
+ + {/* If we have the token from this session, show it */} +
+ +
+
+

+ Your API token from this session +

+

+ Click reveal to show your token +

+
+ +
+
+ + +
+
+ + +
+ +
+ + {lastGeneratedToken()} + + +
+ +
+

Use this token with the X-API-Token header:

+ + curl -H "X-API-Token: {lastGeneratedToken()}" http://your-pulse-url/api/health + +
+
+
+ +
+

+ Note: This token is only available during your current session. + If you lose it after logging out, you'll need to reset your security settings. +

+
+
+
+ + + {/* No token in session storage */} +
+
+

+ API Token Configured +

+

+ An API token was configured during security setup. +

+
+ +
+

+ Important: For security reasons, the API token cannot be retrieved after initial setup. + It is stored as a one-way hash (SHA3-256) and the original value cannot be recovered. +

+
+ +
+

Lost your token? You have two options:

+
    +
  1. If you saved it during setup, use that copy
  2. +
  3. Reset security settings and create a new token
  4. +
+
+
+
+
+ ); +}; \ No newline at end of file diff --git a/frontend-modern/src/components/Settings/QuickSecuritySetup.tsx b/frontend-modern/src/components/Settings/QuickSecuritySetup.tsx index f585c1da4..ad7db855a 100644 --- a/frontend-modern/src/components/Settings/QuickSecuritySetup.tsx +++ b/frontend-modern/src/components/Settings/QuickSecuritySetup.tsx @@ -117,6 +117,11 @@ export const QuickSecuritySetup: Component = () => { setCredentials(newCredentials); setShowCredentials(true); + // Store the API token in sessionStorage so it can be retrieved later in this session + if (newCredentials.apiToken) { + sessionStorage.setItem('pulse_last_api_token', newCredentials.apiToken); + } + // Store the command if manual action needed if (result.command) { (window as any).securityCommand = result.command; diff --git a/frontend-modern/src/components/Settings/Settings.tsx b/frontend-modern/src/components/Settings/Settings.tsx index 048a9ce8b..fc616e74f 100644 --- a/frontend-modern/src/components/Settings/Settings.tsx +++ b/frontend-modern/src/components/Settings/Settings.tsx @@ -2,8 +2,8 @@ import { Component, createSignal, onMount, For, Show, createEffect, onCleanup } import { useWebSocket } from '@/App'; import { showSuccess, showError } from '@/utils/toast'; import { NodeModal } from './NodeModal'; -import { APITokenManager } from './APITokenManager'; import { QuickSecuritySetup } from './QuickSecuritySetup'; +import { CurrentAPIToken } from './CurrentAPIToken'; import { ChangePasswordModal } from './ChangePasswordModal'; import { RemovePasswordModal } from './RemovePasswordModal'; import { SettingsAPI } from '@/api/settings'; @@ -1513,15 +1513,14 @@ const Settings: Component = () => { - {/* API Tokens - Only show if NOT using Quick Security Setup */} - {/* Quick Security Setup manages its own API token via systemd */} - + {/* API Token - Show current token when auth is enabled */} +
-

API Tokens

+

API Token

- Secure API access for automation and exports + Your API token for automation and integrations

- +