Repository: block/goose
File: ui/desktop/src/components/settings/dictation/ElevenLabsKeyInput.tsx (TypeScript)

Code before:
import { useState, useEffect, useRef } from 'react';
import { Input } from '../../ui/input';
import { useConfig } from '../../ConfigContext';
import { ELEVENLABS_API_KEY } from '../../../hooks/dictationConstants';

export const ElevenLabsKeyInput = () => {
  const [elevenLabsApiKey, setElevenLabsApiKey] = useState('');
  const [isLoadingKey, setIsLoadingKey] = useState(false);
  const [hasElevenLabsKey, setHasElevenLabsKey] = useState(false);
  const [validationError, setValidationError] = useState('');
  const [wasMasked, setWasMasked] = useState(false);
  const elevenLabsApiKeyRef = useRef('');
  const { upsert, read, remove } = useConfig();

  useEffect(() => {
    const loadKey = async () => {
      setIsLoadingKey(true);
      try {
        const keyExists = await read(ELEVENLABS_API_KEY, true);
        const hasKey =
          keyExists !== null &&
          keyExists !== '' &&
          (typeof keyExists === 'object' && 'masked_value' in keyExists
            ? keyExists.masked_value
            : keyExists);

        if (hasKey) {
          setHasElevenLabsKey(true);
          setElevenLabsApiKey('••••••••••••••••');
        } else {
          setHasElevenLabsKey(false);
          setElevenLabsApiKey('');
        }
      } catch (error) {
        console.error('Error checking ElevenLabs API key:', error);
      } finally {
        setIsLoadingKey(false);
      }
    };

    loadKey();
  }, [read]);

  useEffect(() => {
    return () => {
      if (elevenLabsApiKeyRef.current && elevenLabsApiKeyRef.current !== '••••••••••••••••') {
        const keyToSave = elevenLabsApiKeyRef.current;
        if (keyToSave.trim()) {
          upsert(ELEVENLABS_API_KEY, keyToSave, true).catch((error) => {
            console.error('Error saving ElevenLabs API key on unmount:', error);

Review comment (security):
if `keyExists` is a non empty string, the `hasKey` will also return true which is not expected behaviour

The `keyExist` variable name is a bit confusing now, can rename it to `response`.

While fixing another issue in this PR https://github.com/block/goose/pull/6662, I have created a function `isSecretKeyConfigured`  to check hasKey and are used in both ElevenLabsKeyInput.ts here and useDictationSettings.ts.   We can use this function. 

Code after:
import { useState, useEffect, useCallback } from 'react';
import { Input } from '../../ui/input';
import { Button } from '../../ui/button';
import { useConfig } from '../../ConfigContext';
import { ELEVENLABS_API_KEY, isSecretKeyConfigured } from '../../../hooks/dictationConstants';
import { setElevenLabsKeyCache } from '../../../hooks/useDictationSettings';

export const ElevenLabsKeyInput = () => {
  const [elevenLabsApiKey, setElevenLabsApiKey] = useState('');
  const [isLoadingKey, setIsLoadingKey] = useState(false);
  const [hasElevenLabsKey, setHasElevenLabsKey] = useState(false);
  const [validationError, setValidationError] = useState('');
  const [isEditing, setIsEditing] = useState(false);
  const { upsert, read, remove } = useConfig();

  const loadKey = useCallback(async () => {
    setIsLoadingKey(true);
    try {
      const response = await read(ELEVENLABS_API_KEY, true);
      const hasKey = isSecretKeyConfigured(response);
      setHasElevenLabsKey(hasKey);
      setElevenLabsKeyCache(hasKey);
    } catch (error) {
      console.error(error);
      setElevenLabsKeyCache(false);
    } finally {
      setIsLoadingKey(false);
    }
  }, [read]);

  useEffect(() => {
    loadKey();
  }, [loadKey]);

  const handleElevenLabsKeyChange = (key: string) => {
    setElevenLabsApiKey(key);
    if (validationError) {
      setValidationError('');
    }
  };

  const handleSave = async () => {
    try {
      const trimmedKey = elevenLabsApiKey.trim();

      if (!trimmedKey) {
        setValidationError('API key is required');
        return;
      }