diff --git a/CHANGELOG.md b/CHANGELOG.md index d829a062b058..35f9169e0027 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### ✨ New Features + +- **feat(api-keys):** add rename support in the permissions modal — editable key name field with validation + --- ## [3.7.4] — 2026-04-28 diff --git a/src/app/(dashboard)/dashboard/api-manager/ApiManagerPageClient.tsx b/src/app/(dashboard)/dashboard/api-manager/ApiManagerPageClient.tsx index a71b38a25893..fff2b31ec3a3 100644 --- a/src/app/(dashboard)/dashboard/api-manager/ApiManagerPageClient.tsx +++ b/src/app/(dashboard)/dashboard/api-manager/ApiManagerPageClient.tsx @@ -6,7 +6,7 @@ import { useCopyToClipboard } from "@/shared/hooks/useCopyToClipboard"; import { useTranslations } from "next-intl"; // Constants for validation -const MAX_KEY_NAME_LENGTH = 100; +const MAX_KEY_NAME_LENGTH = 200; const MAX_SELECTED_MODELS = 500; // Debounce hook for search optimization @@ -232,14 +232,13 @@ export default function ApiManagerPageClient() { const clearError = useCallback(() => setError(null), []); const handleCreateKey = async () => { - // Validate and sanitize input - const sanitizedName = sanitizeInput(newKeyName); - const validation = validateKeyName(sanitizedName, t); - + // Validate raw input first, then sanitize + const validation = validateKeyName(newKeyName, t); if (!validation.valid) { setError(validation.error || t("invalidKeyName")); return; } + const sanitizedName = sanitizeInput(newKeyName); setIsSubmitting(true); clearError(); @@ -322,6 +321,7 @@ export default function ApiManagerPageClient() { }; const handleUpdatePermissions = async ( + name: string, allowedModels: string[], noLog: boolean, allowedConnections: string[], @@ -332,6 +332,14 @@ export default function ApiManagerPageClient() { ) => { if (!editingKey || !editingKey.id) return; + // Validate raw input first, then sanitize + const nameValidation = validateKeyName(name, t); + if (!nameValidation.valid) { + setError(nameValidation.error || t("invalidKeyName")); + return; + } + const sanitizedName = sanitizeInput(name); + // Validate models array if (!Array.isArray(allowedModels)) { setError(t("invalidModelsSelection")); @@ -366,6 +374,7 @@ export default function ApiManagerPageClient() { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ + name: sanitizedName, allowedModels: validModels, allowedConnections: validConnections, noLog, @@ -764,6 +773,7 @@ export default function ApiManagerPageClient() { value={newKeyName} onChange={(e) => setNewKeyName(e.target.value)} placeholder={t("keyNamePlaceholder")} + maxLength={MAX_KEY_NAME_LENGTH} autoFocus />
{t("keyNameDesc")}
{t("keyName")}