diff --git a/app/(dashboard)/sse/page.tsx b/app/(dashboard)/sse/page.tsx index 8f3e0286..a99ca9db 100644 --- a/app/(dashboard)/sse/page.tsx +++ b/app/(dashboard)/sse/page.tsx @@ -1,61 +1,447 @@ "use client" import * as React from "react" -import { useState, useEffect, useCallback } from "react" import { useTranslation } from "react-i18next" +import { RiAddLine, RiArrowLeftSLine, RiArrowRightSLine, RiRefreshLine } from "@remixicon/react" +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" +import { Checkbox } from "@/components/ui/checkbox" +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog" +import { + Drawer, + DrawerContent, + DrawerDescription, + DrawerHeader, + DrawerTitle, +} from "@/components/ui/drawer" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" +import { Field, FieldContent, FieldDescription, FieldGroup, FieldLabel } from "@/components/ui/field" +import { Input } from "@/components/ui/input" import { Page } from "@/components/page" import { PageHeader } from "@/components/page-header" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" +import { Spinner } from "@/components/ui/spinner" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { useSSE } from "@/hooks/use-sse" import { useMessage } from "@/lib/feedback/message" +import type { KmsConfigPayload, KmsKeyInfo, KmsKeyMetadata, KmsServiceStatusResponse } from "@/types/kms" +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from "@/components/ui/alert-dialog" + +const KEY_LIST_LIMIT = 20 +const DEFAULT_PENDING_DELETE_DAYS = 7 + +type ConfigFormState = { + backendType: "local" | "vault" + keyDir: string + filePermissions: string + defaultKeyId: string + timeoutSeconds: string + retryAttempts: string + enableCache: boolean + maxCachedKeys: string + cacheTtlSeconds: string + address: string + vaultToken: string + namespace: string + mountPath: string + kvMount: string + keyPathPrefix: string + skipTlsVerify: boolean +} + +type KeyActionState = + | { + type: "scheduleDelete" | "forceDelete" | "cancelDeletion" + key: KmsKeyInfo + } + | null + +const INITIAL_FORM_STATE: ConfigFormState = { + backendType: "local", + keyDir: "", + filePermissions: "384", + defaultKeyId: "", + timeoutSeconds: "30", + retryAttempts: "3", + enableCache: true, + maxCachedKeys: "1000", + cacheTtlSeconds: "3600", + address: "", + vaultToken: "", + namespace: "", + mountPath: "transit", + kvMount: "secret", + keyPathPrefix: "rustfs/kms/keys", + skipTlsVerify: false, +} + +function getStatusKind(status: KmsServiceStatusResponse | null): "NotConfigured" | "Configured" | "Running" | "Error" { + if (!status?.status) return "NotConfigured" + if (typeof status.status === "object" && status.status && "Error" in status.status) return "Error" + if (status.status === "Running" || status.status === "Configured" || status.status === "NotConfigured") { + return status.status + } + return "Error" +} + +function formatTimestamp(value?: string | null) { + if (!value) return "-" + const date = new Date(value) + if (Number.isNaN(date.getTime())) return value + return date.toLocaleString() +} + +function getKeyDisplayName(key: KmsKeyInfo | KmsKeyMetadata | null) { + if (!key) return "-" + return key.tags?.name ?? key.description ?? key.key_id +} + +function getStateBadgeVariant(value?: string | null) { + const normalized = value?.toLowerCase() ?? "" + if (normalized.includes("pending") || normalized.includes("error") || normalized.includes("unavailable")) { + return "destructive" as const + } + if (normalized.includes("running") || normalized.includes("enabled")) { + return "secondary" as const + } + return "outline" as const +} + +function parseOptionalInteger(value: string) { + const trimmed = value.trim() + if (!trimmed) return undefined + const parsed = Number.parseInt(trimmed, 10) + return Number.isFinite(parsed) ? parsed : undefined +} + +function isAbsolutePath(value: string) { + return /^(?:[A-Za-z]:[\\/]|\\\\|\/)/.test(value.trim()) +} + +function buildFormStateFromStatus(status: KmsServiceStatusResponse | null): ConfigFormState { + if (!status) return INITIAL_FORM_STATE + + const summary = status.config_summary + const backendSummary = summary?.backend_summary + const cacheSummary = summary?.cache_summary + + return { + backendType: status.backend_type === "Vault" ? "vault" : "local", + keyDir: backendSummary?.key_dir ?? "", + filePermissions: String(backendSummary?.file_permissions ?? 384), + defaultKeyId: summary?.default_key_id ?? "", + timeoutSeconds: String(backendSummary?.timeout_seconds ?? 30), + retryAttempts: String(backendSummary?.retry_attempts ?? 3), + enableCache: summary?.enable_cache ?? cacheSummary?.enabled ?? true, + maxCachedKeys: String(summary?.max_cached_keys ?? cacheSummary?.max_cached_keys ?? 1000), + cacheTtlSeconds: String(summary?.cache_ttl_seconds ?? cacheSummary?.cache_ttl_seconds ?? cacheSummary?.ttl_seconds ?? 3600), + address: backendSummary?.address ?? "", + vaultToken: "", + namespace: backendSummary?.namespace ?? "", + mountPath: backendSummary?.mount_path ?? "transit", + kvMount: backendSummary?.kv_mount ?? "secret", + keyPathPrefix: backendSummary?.key_path_prefix ?? "rustfs/kms/keys", + skipTlsVerify: backendSummary?.skip_tls_verify ?? false, + } +} export default function SSEPage() { const { t } = useTranslation() const message = useMessage() - const { getKMSStatus, clearCache, startKMS, stopKMS } = useSSE() - - const [status, setStatus] = useState<{ - status?: string - healthy?: boolean - backend_type?: string - config_summary?: Record - } | null>(null) - const [loading, setLoading] = useState(false) - const [refreshingStatus, setRefreshingStatus] = useState(false) - const [clearingCache, setClearingCache] = useState(false) - const [startingKMS, setStartingKMS] = useState(false) - const [stoppingKMS, setStoppingKMS] = useState(false) - - const loadStatus = useCallback(async () => { - setLoading(true) - try { - const res = (await getKMSStatus()) as { - status?: string - healthy?: boolean - backend_type?: string - config_summary?: Record - } - setStatus(res ?? null) - } catch { - setStatus(null) - } finally { - setLoading(false) + const { + getKMSStatus, + configureKMS, + reconfigureKMS, + clearCache, + startKMS, + stopKMS, + createKey, + getKeyDetails, + getKeyList, + deleteKey, + forceDeleteKey, + cancelKeyDeletion, + } = useSSE() + + const [status, setStatus] = React.useState(null) + const [formState, setFormState] = React.useState(INITIAL_FORM_STATE) + const [loadingStatus, setLoadingStatus] = React.useState(false) + const [refreshingStatus, setRefreshingStatus] = React.useState(false) + const [submittingConfig, setSubmittingConfig] = React.useState(false) + const [clearingCache, setClearingCache] = React.useState(false) + const [startingKMS, setStartingKMS] = React.useState(false) + const [stoppingKMS, setStoppingKMS] = React.useState(false) + + const [keys, setKeys] = React.useState([]) + const [loadingKeys, setLoadingKeys] = React.useState(false) + const [currentMarker, setCurrentMarker] = React.useState("") + const [previousMarkers, setPreviousMarkers] = React.useState([]) + const [nextMarker, setNextMarker] = React.useState(null) + + const [createKeyOpen, setCreateKeyOpen] = React.useState(false) + const [creatingKey, setCreatingKey] = React.useState(false) + const [createKeyName, setCreateKeyName] = React.useState("") + const [createKeyDescription, setCreateKeyDescription] = React.useState("") + const [createKeySetAsDefault, setCreateKeySetAsDefault] = React.useState(false) + + const [selectedKeyId, setSelectedKeyId] = React.useState(null) + const [loadingKeyDetails, setLoadingKeyDetails] = React.useState(false) + const [keyDetails, setKeyDetails] = React.useState(null) + + const [pendingKeyAction, setPendingKeyAction] = React.useState(null) + const [processingKeyAction, setProcessingKeyAction] = React.useState(false) + + const statusKind = React.useMemo(() => getStatusKind(status), [status]) + const isRunning = statusKind === "Running" + const hasConfiguration = statusKind !== "NotConfigured" + const statusBadgeValue = + statusKind === "Error" ? "Error" : typeof status?.status === "string" ? status.status : statusKind + + const loadStatus = React.useCallback( + async (syncForm = false) => { + setLoadingStatus(true) + try { + const res = await getKMSStatus() + setStatus(res) + if (syncForm) { + setFormState((current) => { + const next = buildFormStateFromStatus(res) + if (current.vaultToken && next.backendType === "vault") { + next.vaultToken = current.vaultToken + } + return next + }) + } + } catch (error) { + setStatus(null) + throw error + } finally { + setLoadingStatus(false) + } + }, + [getKMSStatus], + ) + + const loadKeys = React.useCallback( + async (marker = "", notifyOnError = true) => { + setLoadingKeys(true) + try { + const response = await getKeyList({ + limit: KEY_LIST_LIMIT, + marker: marker || undefined, + }) + setKeys(response.keys ?? []) + setCurrentMarker(marker) + setNextMarker(response.truncated ? (response.next_marker ?? null) : null) + } catch (error) { + setKeys([]) + setNextMarker(null) + if (notifyOnError) { + message.error((error as Error).message || t("Failed to fetch KMS keys")) + } + } finally { + setLoadingKeys(false) + } + }, + [getKeyList, message, t], + ) + + React.useEffect(() => { + loadStatus(true).catch((error) => { + message.error((error as Error).message || t("Failed to load KMS status")) + }) + }, [loadStatus, message, t]) + + React.useEffect(() => { + if (!isRunning) { + setKeys([]) + setCurrentMarker("") + setPreviousMarkers([]) + setNextMarker(null) + return } - }, [getKMSStatus]) + setPreviousMarkers([]) + loadKeys("", false).catch(() => undefined) + }, [isRunning, loadKeys]) + + React.useEffect(() => { + if (!selectedKeyId) { + setKeyDetails(null) + return + } + + setLoadingKeyDetails(true) + getKeyDetails(selectedKeyId) + .then((response) => { + setKeyDetails(response.key_metadata ?? null) + }) + .catch((error) => { + setKeyDetails(null) + message.error((error as Error).message || t("Failed to load key details")) + }) + .finally(() => { + setLoadingKeyDetails(false) + }) + }, [getKeyDetails, message, selectedKeyId, t]) + + const getKmsStatusText = React.useCallback(() => { + if (statusKind === "Running") { + return status?.healthy === false ? t("Running (Unhealthy)") : t("Running") + } + if (statusKind === "Configured") return t("Configured") + if (statusKind === "Error") return t("Error") + return t("Not Configured") + }, [status?.healthy, statusKind, t]) + + const getKmsStatusDescription = React.useCallback(() => { + if (statusKind === "Running") { + return status?.healthy ? t("KMS server is running and healthy") : t("KMS server is running but unhealthy") + } + if (statusKind === "Configured") return t("KMS server is configured but not running") + if (statusKind === "Error") return t("KMS server has errors") + return t("KMS server is not configured") + }, [status?.healthy, statusKind, t]) + + const updateFormState = (key: K, value: ConfigFormState[K]) => { + setFormState((current) => ({ ...current, [key]: value })) + } + + const buildConfigPayload = React.useCallback( + (overrideDefaultKeyId?: string): { payload?: KmsConfigPayload; error?: string } => { + const defaultKeyId = (overrideDefaultKeyId ?? formState.defaultKeyId).trim() + const timeoutSeconds = parseOptionalInteger(formState.timeoutSeconds) + const retryAttempts = parseOptionalInteger(formState.retryAttempts) + const maxCachedKeys = parseOptionalInteger(formState.maxCachedKeys) + const cacheTtlSeconds = parseOptionalInteger(formState.cacheTtlSeconds) + + if (formState.backendType === "local") { + if (!isAbsolutePath(formState.keyDir)) { + return { error: t("Please enter an absolute local key directory path") } + } - useEffect(() => { - loadStatus() - }, [loadStatus]) + return { + payload: { + backend_type: "local", + key_dir: formState.keyDir.trim(), + file_permissions: parseOptionalInteger(formState.filePermissions) ?? 384, + default_key_id: defaultKeyId || undefined, + timeout_seconds: timeoutSeconds ?? 30, + retry_attempts: retryAttempts ?? 3, + enable_cache: formState.enableCache, + max_cached_keys: formState.enableCache ? maxCachedKeys ?? 1000 : undefined, + cache_ttl_seconds: formState.enableCache ? cacheTtlSeconds ?? 3600 : undefined, + }, + } + } + + if (!formState.address.trim()) { + return { error: t("Please enter Vault server address") } + } + if (!formState.vaultToken.trim()) { + return { error: t("Please enter Vault token") } + } + if (!formState.mountPath.trim()) { + return { error: t("Please enter Vault transit mount path") } + } + + return { + payload: { + backend_type: "vault", + address: formState.address.trim(), + auth_method: { + Token: { + token: formState.vaultToken.trim(), + }, + }, + namespace: formState.namespace.trim() || null, + mount_path: formState.mountPath.trim(), + kv_mount: formState.kvMount.trim() || null, + key_path_prefix: formState.keyPathPrefix.trim() || null, + skip_tls_verify: formState.skipTlsVerify, + default_key_id: defaultKeyId || undefined, + timeout_seconds: timeoutSeconds ?? 30, + retry_attempts: retryAttempts ?? 3, + enable_cache: formState.enableCache, + max_cached_keys: formState.enableCache ? maxCachedKeys ?? 1000 : undefined, + cache_ttl_seconds: formState.enableCache ? cacheTtlSeconds ?? 3600 : undefined, + }, + } + }, + [formState, t], + ) + + const submitConfiguration = React.useCallback( + async (overrideDefaultKeyId?: string, source: "manual" | "defaultKey" = "manual") => { + const { payload, error } = buildConfigPayload(overrideDefaultKeyId) + if (!payload) { + if (source === "manual") { + message.error(error || t("Failed to save KMS configuration")) + } + return false + } + + setSubmittingConfig(true) + try { + const response = + statusKind === "NotConfigured" ? await configureKMS(payload) : await reconfigureKMS(payload) + + if (response.success) { + if (source === "manual") { + message.success( + statusKind === "NotConfigured" + ? t("KMS configuration saved successfully") + : t("KMS configuration updated successfully"), + ) + } else { + message.success(t("Default SSE key updated successfully")) + } + await loadStatus(true) + return true + } + + message.error(response.message || t("Failed to save KMS configuration")) + return false + } catch (error) { + message.error((error as Error).message || t("Failed to save KMS configuration")) + return false + } finally { + setSubmittingConfig(false) + } + }, + [buildConfigPayload, configureKMS, loadStatus, message, reconfigureKMS, statusKind, t], + ) const handleRefresh = async () => { setRefreshingStatus(true) try { - await loadStatus() + await loadStatus(false) message.success(t("Status refreshed successfully")) - } catch { - message.error(t("Failed to refresh status")) + } catch (error) { + message.error((error as Error).message || t("Failed to refresh status")) } finally { setRefreshingStatus(false) } @@ -64,14 +450,14 @@ export default function SSEPage() { const handleClearCache = async () => { setClearingCache(true) try { - const result = (await clearCache()) as { status?: string; message?: string } - if (result?.status === "success") { + const result = await clearCache() + if (result?.success || result?.status === "success") { message.success(t("Cache cleared successfully")) } else { message.warning(result?.message || t("Cache clear completed with warnings")) } - } catch { - message.error(t("Failed to clear cache")) + } catch (error) { + message.error((error as Error).message || t("Failed to clear cache")) } finally { setClearingCache(false) } @@ -80,15 +466,20 @@ export default function SSEPage() { const handleStartKMS = async () => { setStartingKMS(true) try { - const res = (await startKMS()) as { success?: boolean; status?: string; message?: string } + const force = isRunning + const res = await startKMS(force ? { force: true } : {}) if (res?.success) { - message.success(t("KMS service started successfully")) - await loadStatus() + message.success(force ? t("KMS service restarted successfully") : t("KMS service started successfully")) + await loadStatus(false) } else { - message.error(t("Failed to start KMS service") + ": " + (res?.message || "Unknown error")) + message.error( + (force ? t("Failed to restart KMS service") : t("Failed to start KMS service")) + + ": " + + (res?.message || t("Unknown")), + ) } - } catch { - message.error(t("Failed to start KMS service")) + } catch (error) { + message.error((error as Error).message || t("Failed to start KMS service")) } finally { setStartingKMS(false) } @@ -97,118 +488,786 @@ export default function SSEPage() { const handleStopKMS = async () => { setStoppingKMS(true) try { - const res = (await stopKMS()) as { success?: boolean; status?: string; message?: string } + const res = await stopKMS() if (res?.success) { message.success(t("KMS service stopped successfully")) - await loadStatus() + await loadStatus(false) } else { - message.error(t("Failed to stop KMS service") + ": " + (res?.message || "Unknown error")) + message.error(t("Failed to stop KMS service") + ": " + (res?.message || t("Unknown"))) } - } catch { - message.error(t("Failed to stop KMS service")) + } catch (error) { + message.error((error as Error).message || t("Failed to stop KMS service")) } finally { setStoppingKMS(false) } } - const getKmsStatusText = () => { - if (!status) return t("Not Configured") - if (status.status === "Running") { - return status.healthy ? t("Running") : t("Running (Unhealthy)") + const handleCreateKey = async () => { + setCreatingKey(true) + try { + const tags: Record = { created_by: "console" } + if (createKeyName.trim()) { + tags.name = createKeyName.trim() + } + const response = await createKey({ + key_usage: "EncryptDecrypt", + description: createKeyDescription.trim() || undefined, + tags, + }) + const createdKeyId = response.key_id ?? response.key_metadata?.key_id + + if (response.success === false) { + message.error(response.message || t("Failed to create KMS key")) + return + } + + message.success(t("KMS key created successfully")) + setCreateKeyOpen(false) + setCreateKeyName("") + setCreateKeyDescription("") + setCreateKeySetAsDefault(false) + + if (createKeySetAsDefault && createdKeyId) { + const updated = await submitConfiguration(createdKeyId, "defaultKey") + if (!updated) { + message.warning(t("Key created but could not update the default SSE key. Save the configuration form and try again.")) + } + } + + if (isRunning) { + await loadKeys(currentMarker, false) + } + } catch (error) { + message.error((error as Error).message || t("Failed to create KMS key")) + } finally { + setCreatingKey(false) } - if (status.status === "Configured") return t("Configured") - if (status.status === "NotConfigured") return t("Not Configured") - return t("Unknown") } - const getKmsStatusDescription = () => { - if (!status) return t("KMS server is not configured") - if (status.status === "Running") { - return status.healthy ? t("KMS server is running and healthy") : t("KMS server is running but unhealthy") + const handleConfirmKeyAction = async () => { + if (!pendingKeyAction) return + + setProcessingKeyAction(true) + try { + if (pendingKeyAction.type === "scheduleDelete") { + const response = await deleteKey(pendingKeyAction.key.key_id, { + pending_window_in_days: DEFAULT_PENDING_DELETE_DAYS, + }) + if (response.success === false) { + message.error(response.message || t("Failed to schedule key deletion")) + return + } + message.success(t("Key deletion scheduled successfully")) + } + + if (pendingKeyAction.type === "forceDelete") { + const response = await forceDeleteKey(pendingKeyAction.key.key_id) + if (response.success === false) { + message.error(response.message || t("Failed to force delete key")) + return + } + message.success(t("Key deleted immediately")) + } + + if (pendingKeyAction.type === "cancelDeletion") { + const response = await cancelKeyDeletion(pendingKeyAction.key.key_id) + if (response.success === false) { + message.error(response.message || t("Failed to cancel key deletion")) + return + } + message.success(t("Key deletion canceled successfully")) + } + + setPendingKeyAction(null) + await loadKeys(currentMarker, false) + } catch (error) { + message.error((error as Error).message || t("Failed to update key status")) + } finally { + setProcessingKeyAction(false) } - if (status.status === "Configured") return t("KMS server is configured but not running") - return t("KMS server status unknown") } - const hasConfiguration = status?.status && status.status !== "NotConfigured" + const keyActionTitle = + pendingKeyAction?.type === "forceDelete" + ? t("Delete Key Immediately") + : pendingKeyAction?.type === "cancelDeletion" + ? t("Cancel Key Deletion") + : t("Schedule Key Deletion") + + const keyActionDescription = + pendingKeyAction?.type === "forceDelete" + ? t("This permanently deletes the key immediately and cannot be undone.") + : pendingKeyAction?.type === "cancelDeletion" + ? t("This restores the key from the pending deletion state.") + : t("This schedules the key for deletion using the default pending window.") return ( - - - {t("Configure server-side encryption for your objects using external key management services.")} -

- } - > -

{t("Server-Side Encryption (SSE) Configuration")}

-
- -
- - -
- {t("KMS Status Overview")} - - {loading ? t("Loading...") : getKmsStatusText()} - -
- {getKmsStatusDescription()} - {status?.backend_type && ( - - {t("Backend")}: {status.backend_type} - - )} -
- -
-
-

{t("Backend Type")}

-

{status?.backend_type ?? t("Not configured")}

-
-
-

{t("Status")}

-

{status?.status ?? t("Not configured")}

+ <> + + + {t("Configure server-side encryption for your objects using external key management services.")} +

+ } + > +

{t("Server-Side Encryption (SSE) Configuration")}

+
+ +
+ + +
+ {t("KMS Status Overview")} + + {loadingStatus ? t("Loading...") : getKmsStatusText()} +
-
-

{t("Health")}

-

{status?.healthy ? t("Healthy") : t("Unhealthy")}

+ {getKmsStatusDescription()} + {status?.backend_type && ( + + {t("Backend")}: {status.backend_type} + + )} + + +
+
+

{t("Backend Type")}

+

{status?.backend_type ?? t("Not configured")}

+
+
+

{t("Status")}

+

{loadingStatus ? t("Loading...") : getKmsStatusText()}

+
+
+

{t("Health")}

+

+ {status?.healthy == null ? t("Unknown") : status.healthy ? t("Healthy") : t("Unhealthy")} +

+
+
+

{t("Default SSE Key")}

+

+ {status?.config_summary?.default_key_id || t("Not set")} +

+
-
-
- - - {hasConfiguration && (status?.status === "Configured" || status?.status === "Error") && ( - + + {statusKind === "Error" && ( + + {t("KMS service has errors")} + + {typeof status?.status === "object" && status?.status && "Error" in status.status + ? status.status.Error + : t("KMS server status unknown")} + + )} - {hasConfiguration && status?.status === "Running" && ( - + + {statusKind === "Configured" && ( + + {t("KMS configured but not started")} + {t("Start KMS to make SSE and key management available.")} + )} + +
+ + + {hasConfiguration && ( + + )} + + {hasConfiguration && ( + + + + + + + {clearingCache ? t("Clearing cache...") : t("Clear Cache")} + + + + {stoppingKMS ? t("Stopping KMS...") : t("Stop KMS")} + + + + )} +
+ + + + + + {t("KMS Configuration")} + {t("Configure the KMS backend, cache policy, and default SSE key.")} + + +
{ + event.preventDefault() + void submitConfiguration() + }} + > + + + {t("KMS Backend")} + + + + {t("Choose the backend used by SSE/KMS.")} + + + + {t("Default SSE Key")} + + updateFormState("defaultKeyId", event.target.value)} + placeholder={t("Enter the default SSE key ID")} + /> + + {t("This key is used as the platform default for SSE-KMS and SSE-S3.")} + + + + {formState.backendType === "local" ? ( + + + {t("Local Key Directory")} + + updateFormState("keyDir", event.target.value)} + placeholder={t("Enter an absolute path such as D:/data/kms-keys")} + /> + + {t("The directory must be an absolute path on the server.")} + + + + {t("File Permissions")} + + updateFormState("filePermissions", event.target.value)} + placeholder="384" + /> + + {t("Use decimal values such as 384 for 0o600.")} + + + ) : ( +
+ + {t("Vault token authentication only")} + {t("Vault AppRole is not supported in the first version of this console.")} + + + + + {t("Vault Server Address")} + + updateFormState("address", event.target.value)} + placeholder="http://127.0.0.1:8200" + /> + + + + + {t("Vault Token")} + + updateFormState("vaultToken", event.target.value)} + placeholder={t("Enter your Vault authentication token")} + autoComplete="off" + /> + + {t("Required: Vault authentication token")} + + + + + + {t("Vault Namespace")} + + updateFormState("namespace", event.target.value)} + placeholder={t("Optional Vault namespace")} + /> + + + + + {t("Transit Mount Path")} + + updateFormState("mountPath", event.target.value)} + placeholder="transit" + /> + + + + + {t("KV Mount")} + + updateFormState("kvMount", event.target.value)} + placeholder="secret" + /> + + + + + {t("Key Path Prefix")} + + updateFormState("keyPathPrefix", event.target.value)} + placeholder="rustfs/kms/keys" + /> + + + + +
+ updateFormState("skipTlsVerify", checked === true)} + id="skipTlsVerify" + /> + +
+
+ )} + + + + {t("Timeout (seconds)")} + + updateFormState("timeoutSeconds", event.target.value)} + /> + + + + + {t("Retry Attempts")} + + updateFormState("retryAttempts", event.target.value)} + /> + + + + +
+
+ updateFormState("enableCache", checked === true)} + id="enableCache" + /> + +
+ + {formState.enableCache && ( + + + {t("Max Cached Keys")} + + updateFormState("maxCachedKeys", event.target.value)} + /> + + + + + {t("Cache TTL (seconds)")} + + updateFormState("cacheTtlSeconds", event.target.value)} + /> + + + + )} +
+ +
+ + +
+
+
+
+ + {isRunning && ( + + +
+
+ {t("KMS Keys Management")} + {t("Create, rotate, and inspect the keys managed by your KMS backend.")} +
+
+ + +
+
+
+ + + {t("Two-stage key deletion")} + {t("Keys in PendingDeletion can still be restored or deleted immediately.")} + + + {loadingKeys ? ( +
+ +
+ ) : keys.length === 0 ? ( +
+ {t("No KMS keys found")} +
+ ) : ( + + + + {t("Name")} + {t("KMS Key ID")} + {t("Status")} + {t("Algorithm")} + {t("Usage")} + {t("Created")} + {t("Actions")} + + + + {keys.map((key) => { + const isPendingDeletion = (key.status ?? "").toLowerCase().includes("pendingdeletion") + return ( + + {getKeyDisplayName(key)} + + {key.key_id} + + + {key.status || "-"} + + {key.algorithm || "-"} + {key.usage || "-"} + {formatTimestamp(key.created_at)} + +
+ + + + + + setSelectedKeyId(key.key_id)}> + {t("View Details")} + + {!isPendingDeletion && ( + setPendingKeyAction({ type: "scheduleDelete", key })}> + {t("Schedule Deletion")} + + )} + {isPendingDeletion && ( + setPendingKeyAction({ type: "cancelDeletion", key })}> + {t("Cancel Deletion")} + + )} + + setPendingKeyAction({ type: "forceDelete", key })} + className="text-destructive focus:text-destructive" + > + {t("Delete Immediately")} + + + +
+
+
+ ) + })} +
+
+ )} + +
+

+ {t("Showing up to {count} keys per page", { count: KEY_LIST_LIMIT })} +

+
+ + +
+
+
+
+ )} +
+ + + { + setCreateKeyOpen(open) + if (!open) { + setCreateKeyName("") + setCreateKeyDescription("") + setCreateKeySetAsDefault(false) + } + }} + > + + + {t("Create New Key")} + {t("Create a new KMS key and optionally make it the default SSE key.")} + + +
+ + {t("Key Name")} + + setCreateKeyName(event.target.value)} + placeholder={t("Optional display name for the key")} + /> + + + + + {t("Description")} + + setCreateKeyDescription(event.target.value)} + placeholder={t("Describe the purpose of this key")} + /> + + + +
+ setCreateKeySetAsDefault(checked === true)} + id="setAsDefaultKey" + /> +
- - - - - - {t("KMS Configuration")} - {t("Full KMS configuration form - coming soon")} - - -
- +
+ + + + + + + + + !open && setSelectedKeyId(null)} direction="right"> + + + {t("KMS Key Details")} + {selectedKeyId || ""} + + +
+ {loadingKeyDetails ? ( +
+ +
+ ) : !keyDetails ? ( +
+ {t("No key details available")} +
+ ) : ( + <> +
+
+

{t("Name")}

+

{getKeyDisplayName(keyDetails)}

+
+
+

{t("State")}

+
+ {keyDetails.key_state || "-"} +
+
+
+

{t("KMS Key ID")}

+

{keyDetails.key_id}

+
+
+

{t("Usage")}

+

{keyDetails.key_usage || "-"}

+
+
+

{t("Creation Date")}

+

{formatTimestamp(keyDetails.creation_date)}

+
+
+

{t("Deletion Date")}

+

{formatTimestamp(keyDetails.deletion_date)}

+
+
+

{t("Origin")}

+

{keyDetails.origin || "-"}

+
+
+

{t("Key Manager")}

+

{keyDetails.key_manager || "-"}

+
+
+ + {keyDetails.description && ( +
+

{t("Description")}

+

{keyDetails.description}

+
+ )} + +
+

{t("Tags")}

+
+ {Object.entries(keyDetails.tags ?? {}).length > 0 ? ( + Object.entries(keyDetails.tags ?? {}).map(([key, value]) => ( + + {key}: {value} + + )) + ) : ( + {t("No tags")} + )} +
+
+ + )} +
+
+
+ + !open && setPendingKeyAction(null)}> + + + {keyActionTitle} + {keyActionDescription} + + + {t("Cancel")} + + {processingKeyAction ? : null} + {pendingKeyAction?.type === "cancelDeletion" ? t("Restore Key") : t("Confirm")} + + + + + ) } diff --git a/components/auth/login-form.tsx b/components/auth/login-form.tsx index 4294373d..d77d7bde 100644 --- a/components/auth/login-form.tsx +++ b/components/auth/login-form.tsx @@ -71,7 +71,7 @@ export function LoginForm({
diff --git a/hooks/use-sse.ts b/hooks/use-sse.ts index 6cce980b..48144eb7 100644 --- a/hooks/use-sse.ts +++ b/hooks/use-sse.ts @@ -2,35 +2,54 @@ import { useCallback } from "react" import { useApi } from "@/contexts/api-context" +import type { + KmsCancelDeletionRequest, + KmsConfigPayload, + KmsCreateKeyRequest, + KmsCreateKeyResponse, + KmsDeleteKeyOptions, + KmsKeyDetailResponse, + KmsKeyListResponse, + KmsMutationResponse, + KmsServiceStatusResponse, + KmsStartRequest, +} from "@/types/kms" export function useSSE() { const api = useApi() - const getKMSStatus = useCallback(async () => { - return api.get("/kms/service-status") + const getKMSStatus = useCallback(async (): Promise => { + return (await api.get("/kms/service-status")) as KmsServiceStatusResponse }, [api]) const configureKMS = useCallback( - async (data: Record) => { - return api.post("/kms/configure", data) + async (data: KmsConfigPayload): Promise => { + return (await api.post("/kms/configure", data)) as KmsMutationResponse }, [api], ) - const startKMS = useCallback(async () => { - return api.post("/kms/start", {}) + const reconfigureKMS = useCallback( + async (data: KmsConfigPayload): Promise => { + return (await api.post("/kms/reconfigure", data)) as KmsMutationResponse + }, + [api], + ) + + const startKMS = useCallback(async (data: KmsStartRequest = {}): Promise => { + return (await api.post("/kms/start", data)) as KmsMutationResponse }, [api]) - const stopKMS = useCallback(async () => { - return api.post("/kms/stop", {}) + const stopKMS = useCallback(async (): Promise => { + return (await api.post("/kms/stop", {})) as KmsMutationResponse }, [api]) const getConfiguration = useCallback(async () => { return api.get("/kms/config") }, [api]) - const clearCache = useCallback(async () => { - return api.post("/kms/clear-cache", {}) + const clearCache = useCallback(async (): Promise => { + return (await api.post("/kms/clear-cache", {})) as KmsMutationResponse }, [api]) const getDetailedStatus = useCallback(async () => { @@ -38,47 +57,62 @@ export function useSSE() { }, [api]) const createKey = useCallback( - async (data: { KeyUsage?: string; Description?: string; Tags?: Record }) => { + async (data: KmsCreateKeyRequest): Promise => { const requestData = { - key_usage: data.KeyUsage || "EncryptDecrypt", - description: data.Description, - tags: data.Tags, + key_usage: data.key_usage || "EncryptDecrypt", + description: data.description, + tags: data.tags, } - return api.post("/kms/keys", requestData) + return (await api.post("/kms/keys", requestData)) as KmsCreateKeyResponse }, [api], ) const getKeyDetails = useCallback( - async (keyId: string) => { - return api.get(`/kms/keys/${keyId}`) + async (keyId: string): Promise => { + return (await api.get(`/kms/keys/${keyId}`)) as KmsKeyDetailResponse }, [api], ) const getKeyList = useCallback( - async (params?: { limit?: number; marker?: string }) => { + async (params?: { limit?: number; marker?: string }): Promise => { const queryParams = new URLSearchParams() if (params?.limit) queryParams.append("limit", params.limit.toString()) if (params?.marker) queryParams.append("marker", params.marker) const url = queryParams.toString() ? `/kms/keys?${queryParams}` : "/kms/keys" - return api.get(url) + return (await api.get(url)) as KmsKeyListResponse }, [api], ) const deleteKey = useCallback( - async (keyId: string) => { - const url = `/kms/keys/delete?keyId=${encodeURIComponent(keyId)}` - return api.delete(url) + async (keyId: string, options: KmsDeleteKeyOptions = {}): Promise => { + const queryParams = new URLSearchParams({ keyId: keyId }) + if (options.pending_window_in_days != null) { + queryParams.append("pending_window_in_days", String(options.pending_window_in_days)) + } + if (options.force_immediate) { + queryParams.append("force_immediate", "true") + } + const url = `/kms/keys/delete?${queryParams.toString()}` + return (await api.delete(url)) as KmsMutationResponse }, [api], ) const forceDeleteKey = useCallback( - async (keyId: string) => { - const url = `/kms/keys/delete?keyId=${encodeURIComponent(keyId)}&force_immediate=true` - return api.delete(url) + async (keyId: string): Promise => { + return deleteKey(keyId, { force_immediate: true }) + }, + [deleteKey], + ) + + const cancelKeyDeletion = useCallback( + async (request: string | KmsCancelDeletionRequest): Promise => { + const keyId = typeof request === "string" ? request : request.key_id + const url = `/kms/keys/cancel-deletion?keyId=${encodeURIComponent(keyId)}` + return (await api.post(url, typeof request === "string" ? {} : request)) as KmsMutationResponse }, [api], ) @@ -86,6 +120,7 @@ export function useSSE() { return { getKMSStatus, configureKMS, + reconfigureKMS, startKMS, stopKMS, getConfiguration, @@ -96,5 +131,6 @@ export function useSSE() { getKeyList, deleteKey, forceDeleteKey, + cancelKeyDeletion, } } diff --git a/i18n/locales/ar-MA.json b/i18n/locales/ar-MA.json index e78301b7..263ecece 100644 --- a/i18n/locales/ar-MA.json +++ b/i18n/locales/ar-MA.json @@ -888,5 +888,71 @@ "Completing SSO login...": "جارٍ إكمال تسجيل الدخول عبر SSO...", "SSO Login Failed": "فشل تسجيل الدخول عبر SSO", "SSO Login Success": "تم تسجيل الدخول عبر SSO بنجاح", - "SSO login failed: invalid callback": "فشل تسجيل الدخول عبر SSO: عنوان callback غير صالح" + "SSO login failed: invalid callback": "فشل تسجيل الدخول عبر SSO: عنوان callback غير صالح", + "Advanced Actions": "إجراءات متقدمة", + "Choose the backend used by SSE/KMS.": "اختر الواجهة الخلفية المستخدمة من SSE/KMS.", + "Clearing cache...": "جارٍ مسح ذاكرة التخزين المؤقت...", + "Configure the KMS backend, cache policy, and default SSE key.": "اضبط واجهة KMS الخلفية وسياسة التخزين المؤقت ومفتاح SSE الافتراضي.", + "Create a new KMS key and optionally make it the default SSE key.": "أنشئ مفتاح KMS جديدًا واجعله اختياريًا مفتاح SSE الافتراضي.", + "Default SSE Key": "مفتاح SSE الافتراضي", + "Default SSE key updated successfully": "تم تحديث مفتاح SSE الافتراضي بنجاح", + "Delete Immediately": "حذف فورًا", + "Delete Key Immediately": "حذف المفتاح فورًا", + "Describe the purpose of this key": "صف غرض هذا المفتاح", + "Enable KMS Cache": "تفعيل ذاكرة تخزين KMS المؤقتة", + "Enter an absolute path such as D:/data/kms-keys": "أدخل مسارًا مطلقًا مثل D:/data/kms-keys", + "Enter the default SSE key ID": "أدخل معرّف مفتاح SSE الافتراضي", + "Failed to cancel key deletion": "فشل إلغاء حذف المفتاح", + "Failed to create KMS key": "فشل إنشاء مفتاح KMS", + "Failed to force delete key": "فشل الحذف الفوري للمفتاح", + "Failed to restart KMS service": "فشل إعادة تشغيل خدمة KMS", + "Failed to save KMS configuration": "فشل حفظ إعدادات KMS", + "Failed to schedule key deletion": "فشل جدولة حذف المفتاح", + "Failed to update key status": "فشل تحديث حالة المفتاح", + "KMS Backend": "واجهة KMS الخلفية", + "KMS Key Details": "تفاصيل مفتاح KMS", + "KMS configuration saved successfully": "تم حفظ إعدادات KMS بنجاح", + "KMS configuration updated successfully": "تم تحديث إعدادات KMS بنجاح", + "KMS configured but not started": "تم إعداد KMS لكنه غير مشغّل", + "KMS key created successfully": "تم إنشاء مفتاح KMS بنجاح", + "KMS service restarted successfully": "تم إعادة تشغيل خدمة KMS بنجاح", + "KV Mount": "تثبيت KV", + "Key Path Prefix": "بادئة مسار المفتاح", + "Key created but could not update the default SSE key. Save the configuration form and try again.": "تم إنشاء المفتاح لكن تعذّر تحديث مفتاح SSE الافتراضي. احفظ نموذج الإعداد ثم أعد المحاولة.", + "Key deleted immediately": "تم حذف المفتاح فورًا", + "Key deletion canceled successfully": "تم إلغاء حذف المفتاح بنجاح", + "Key deletion scheduled successfully": "تم جدولة حذف المفتاح بنجاح", + "Keys in PendingDeletion can still be restored or deleted immediately.": "لا يزال بإمكان استعادة المفاتيح في حالة PendingDeletion أو حذفها فورًا.", + "Local Key Directory": "دليل المفاتيح المحلي", + "Local filesystem": "نظام الملفات المحلي", + "No key details available": "لا تتوفر تفاصيل للمفتاح", + "Not set": "غير مضبوط", + "Optional Vault namespace": "مساحة أسماء Vault اختيارية", + "Optional display name for the key": "اسم عرض اختياري للمفتاح", + "Please enter Vault transit mount path": "يُرجى إدخال مسار تثبيت transit في Vault", + "Please enter an absolute local key directory path": "يُرجى إدخال مسار مطلق لدليل المفاتيح المحلي", + "Reconfigure KMS": "إعادة تهيئة KMS", + "Reset to Current Status": "إعادة التعيين إلى الحالة الحالية", + "Restart KMS": "إعادة تشغيل KMS", + "Restore Key": "استعادة المفتاح", + "Schedule Deletion": "جدولة الحذف", + "Schedule Key Deletion": "جدولة حذف المفتاح", + "Set as default SSE key": "تعيين كمفتاح SSE افتراضي", + "Showing up to {count} keys per page": "عرض ما يصل إلى {count} مفتاحًا لكل صفحة", + "Skip TLS verification": "تخطي التحقق من TLS", + "Start KMS to make SSE and key management available.": "شغّل KMS لتمكين SSE وإدارة المفاتيح.", + "Stopping KMS...": "جارٍ إيقاف KMS...", + "The directory must be an absolute path on the server.": "يجب أن يكون الدليل مسارًا مطلقًا على الخادم.", + "This key is used as the platform default for SSE-KMS.": "يُستخدم هذا المفتاح كافتراضي للمنصة لـ SSE-KMS.", + "This permanently deletes the key immediately and cannot be undone.": "يحذف المفتاح نهائيًا فورًا ولا يمكن التراجع.", + "This restores the key from the pending deletion state.": "يستعيد المفتاح من حالة الحذف المعلّق.", + "This schedules the key for deletion using the default pending window.": "يجدول حذف المفتاح باستخدام نافذة الانتظار الافتراضية.", + "This will update the current KMS configuration after key creation.": "سيحدّث إعدادات KMS الحالية بعد إنشاء المفتاح.", + "Timeout (seconds)": "المهلة (ثوانٍ)", + "Two-stage key deletion": "حذف المفتاح على مرحلتين", + "Use decimal values such as 384 for 0o600.": "استخدم قيمًا عشرية مثل 384 لـ 0o600.", + "Vault AppRole is not supported in the first version of this console.": "Vault AppRole غير مدعوم في الإصدار الأول من هذه الوحدة.", + "Vault Namespace": "مساحة أسماء Vault", + "Vault token authentication only": "مصادقة رمز Vault فقط", + "View Details": "عرض التفاصيل" } diff --git a/i18n/locales/de-DE.json b/i18n/locales/de-DE.json index 14c9c81f..415dc0c4 100644 --- a/i18n/locales/de-DE.json +++ b/i18n/locales/de-DE.json @@ -901,5 +901,71 @@ "Completing SSO login...": "SSO-Anmeldung wird abgeschlossen...", "SSO Login Failed": "SSO-Anmeldung fehlgeschlagen", "SSO Login Success": "SSO-Anmeldung erfolgreich", - "SSO login failed: invalid callback": "SSO-Anmeldung fehlgeschlagen: ungültiger Callback" + "SSO login failed: invalid callback": "SSO-Anmeldung fehlgeschlagen: ungültiger Callback", + "Advanced Actions": "Erweiterte Aktionen", + "Choose the backend used by SSE/KMS.": "Wählen Sie das Backend für SSE/KMS.", + "Clearing cache...": "Cache wird geleert...", + "Configure the KMS backend, cache policy, and default SSE key.": "Konfigurieren Sie KMS-Backend, Cache-Richtlinie und den Standard-SSE-Schlüssel.", + "Create a new KMS key and optionally make it the default SSE key.": "Neuen KMS-Schlüssel erstellen und optional als Standard-SSE-Schlüssel festlegen.", + "Default SSE Key": "Standard-SSE-Schlüssel", + "Default SSE key updated successfully": "Standard-SSE-Schlüssel erfolgreich aktualisiert", + "Delete Immediately": "Sofort löschen", + "Delete Key Immediately": "Schlüssel sofort löschen", + "Describe the purpose of this key": "Zweck dieses Schlüssels beschreiben", + "Enable KMS Cache": "KMS-Cache aktivieren", + "Enter an absolute path such as D:/data/kms-keys": "Absoluten Pfad eingeben, z. B. D:/data/kms-keys", + "Enter the default SSE key ID": "Standard-SSE-Schlüssel-ID eingeben", + "Failed to cancel key deletion": "Löschung des Schlüssels konnte nicht abgebrochen werden", + "Failed to create KMS key": "KMS-Schlüssel konnte nicht erstellt werden", + "Failed to force delete key": "Sofortiges Löschen des Schlüssels fehlgeschlagen", + "Failed to restart KMS service": "KMS-Dienst konnte nicht neu gestartet werden", + "Failed to save KMS configuration": "KMS-Konfiguration konnte nicht gespeichert werden", + "Failed to schedule key deletion": "Geplante Schlüssellöschung fehlgeschlagen", + "Failed to update key status": "Schlüsselstatus konnte nicht aktualisiert werden", + "KMS Backend": "KMS-Backend", + "KMS Key Details": "KMS-Schlüsseldetails", + "KMS configuration saved successfully": "KMS-Konfiguration erfolgreich gespeichert", + "KMS configuration updated successfully": "KMS-Konfiguration erfolgreich aktualisiert", + "KMS configured but not started": "KMS konfiguriert, aber nicht gestartet", + "KMS key created successfully": "KMS-Schlüssel erfolgreich erstellt", + "KMS service restarted successfully": "KMS-Dienst erfolgreich neu gestartet", + "KV Mount": "KV-Mount", + "Key Path Prefix": "Schlüsselpfad-Präfix", + "Key created but could not update the default SSE key. Save the configuration form and try again.": "Schlüssel erstellt, Standard-SSE-Schlüssel konnte nicht aktualisiert werden. Speichern Sie das Konfigurationsformular und versuchen Sie es erneut.", + "Key deleted immediately": "Schlüssel sofort gelöscht", + "Key deletion canceled successfully": "Schlüssellöschung erfolgreich abgebrochen", + "Key deletion scheduled successfully": "Schlüssellöschung erfolgreich geplant", + "Keys in PendingDeletion can still be restored or deleted immediately.": "Schlüssel im Status PendingDeletion können weiterhin wiederhergestellt oder sofort gelöscht werden.", + "Local Key Directory": "Lokales Schlüsselverzeichnis", + "Local filesystem": "Lokales Dateisystem", + "No key details available": "Keine Schlüsseldetails verfügbar", + "Not set": "Nicht festgelegt", + "Optional Vault namespace": "Optionaler Vault-Namespace", + "Optional display name for the key": "Optionaler Anzeigename für den Schlüssel", + "Please enter Vault transit mount path": "Bitte Vault-Transit-Mount-Pfad eingeben", + "Please enter an absolute local key directory path": "Bitte einen absoluten Pfad zum lokalen Schlüsselverzeichnis eingeben", + "Reconfigure KMS": "KMS neu konfigurieren", + "Reset to Current Status": "Auf aktuellen Status zurücksetzen", + "Restart KMS": "KMS neu starten", + "Restore Key": "Schlüssel wiederherstellen", + "Schedule Deletion": "Löschung planen", + "Schedule Key Deletion": "Schlüssellöschung planen", + "Set as default SSE key": "Als Standard-SSE-Schlüssel festlegen", + "Showing up to {count} keys per page": "Bis zu {count} Schlüssel pro Seite", + "Skip TLS verification": "TLS-Überprüfung überspringen", + "Start KMS to make SSE and key management available.": "Starten Sie KMS, um SSE und Schlüsselverwaltung zu nutzen.", + "Stopping KMS...": "KMS wird gestoppt...", + "The directory must be an absolute path on the server.": "Das Verzeichnis muss ein absoluter Pfad auf dem Server sein.", + "This key is used as the platform default for SSE-KMS.": "Dieser Schlüssel ist die Plattform-Standardvorgabe für SSE-KMS.", + "This permanently deletes the key immediately and cannot be undone.": "Der Schlüssel wird sofort dauerhaft gelöscht und kann nicht rückgängig gemacht werden.", + "This restores the key from the pending deletion state.": "Stellt den Schlüssel aus dem ausstehenden Löschzustand wieder her.", + "This schedules the key for deletion using the default pending window.": "Plant die Schlüssellöschung mit dem Standard-Wartefenster.", + "This will update the current KMS configuration after key creation.": "Aktualisiert die aktuelle KMS-Konfiguration nach der Schlüsselerstellung.", + "Timeout (seconds)": "Timeout (Sekunden)", + "Two-stage key deletion": "Zweistufige Schlüssellöschung", + "Use decimal values such as 384 for 0o600.": "Dezimalwerte verwenden, z. B. 384 für 0o600.", + "Vault AppRole is not supported in the first version of this console.": "Vault AppRole wird in der ersten Version dieser Konsole nicht unterstützt.", + "Vault Namespace": "Vault-Namespace", + "Vault token authentication only": "Nur Vault-Token-Authentifizierung", + "View Details": "Details anzeigen" } diff --git a/i18n/locales/en-US.json b/i18n/locales/en-US.json index 20cf4d4f..dbb48159 100644 --- a/i18n/locales/en-US.json +++ b/i18n/locales/en-US.json @@ -952,5 +952,71 @@ "Validate": "Validate", "Validating...": "Validating...", "View and manage persisted OIDC providers.": "View and manage persisted OIDC providers.", - "You have unsaved OIDC changes. Do you want to discard them?": "You have unsaved OIDC changes. Do you want to discard them?" + "You have unsaved OIDC changes. Do you want to discard them?": "You have unsaved OIDC changes. Do you want to discard them?", + "Advanced Actions": "Advanced Actions", + "Choose the backend used by SSE/KMS.": "Choose the backend used by SSE/KMS.", + "Clearing cache...": "Clearing cache...", + "Configure the KMS backend, cache policy, and default SSE key.": "Configure the KMS backend, cache policy, and default SSE key.", + "Create a new KMS key and optionally make it the default SSE key.": "Create a new KMS key and optionally make it the default SSE key.", + "Default SSE Key": "Default SSE Key", + "Default SSE key updated successfully": "Default SSE key updated successfully", + "Delete Immediately": "Delete Immediately", + "Delete Key Immediately": "Delete Key Immediately", + "Describe the purpose of this key": "Describe the purpose of this key", + "Enable KMS Cache": "Enable KMS Cache", + "Enter an absolute path such as D:/data/kms-keys": "Enter an absolute path such as D:/data/kms-keys", + "Enter the default SSE key ID": "Enter the default SSE key ID", + "Failed to cancel key deletion": "Failed to cancel key deletion", + "Failed to create KMS key": "Failed to create KMS key", + "Failed to force delete key": "Failed to force delete key", + "Failed to restart KMS service": "Failed to restart KMS service", + "Failed to save KMS configuration": "Failed to save KMS configuration", + "Failed to schedule key deletion": "Failed to schedule key deletion", + "Failed to update key status": "Failed to update key status", + "KMS Backend": "KMS Backend", + "KMS Key Details": "KMS Key Details", + "KMS configuration saved successfully": "KMS configuration saved successfully", + "KMS configuration updated successfully": "KMS configuration updated successfully", + "KMS configured but not started": "KMS configured but not started", + "KMS key created successfully": "KMS key created successfully", + "KMS service restarted successfully": "KMS service restarted successfully", + "KV Mount": "KV Mount", + "Key Path Prefix": "Key Path Prefix", + "Key created but could not update the default SSE key. Save the configuration form and try again.": "Key created but could not update the default SSE key. Save the configuration form and try again.", + "Key deleted immediately": "Key deleted immediately", + "Key deletion canceled successfully": "Key deletion canceled successfully", + "Key deletion scheduled successfully": "Key deletion scheduled successfully", + "Keys in PendingDeletion can still be restored or deleted immediately.": "Keys in PendingDeletion can still be restored or deleted immediately.", + "Local Key Directory": "Local Key Directory", + "Local filesystem": "Local filesystem", + "No key details available": "No key details available", + "Not set": "Not set", + "Optional Vault namespace": "Optional Vault namespace", + "Optional display name for the key": "Optional display name for the key", + "Please enter Vault transit mount path": "Please enter Vault transit mount path", + "Please enter an absolute local key directory path": "Please enter an absolute local key directory path", + "Reconfigure KMS": "Reconfigure KMS", + "Reset to Current Status": "Reset to Current Status", + "Restart KMS": "Restart KMS", + "Restore Key": "Restore Key", + "Schedule Deletion": "Schedule Deletion", + "Schedule Key Deletion": "Schedule Key Deletion", + "Set as default SSE key": "Set as default SSE key", + "Showing up to {count} keys per page": "Showing up to {count} keys per page", + "Skip TLS verification": "Skip TLS verification", + "Start KMS to make SSE and key management available.": "Start KMS to make SSE and key management available.", + "Stopping KMS...": "Stopping KMS...", + "The directory must be an absolute path on the server.": "The directory must be an absolute path on the server.", + "This key is used as the platform default for SSE-KMS.": "This key is used as the platform default for SSE-KMS.", + "This permanently deletes the key immediately and cannot be undone.": "This permanently deletes the key immediately and cannot be undone.", + "This restores the key from the pending deletion state.": "This restores the key from the pending deletion state.", + "This schedules the key for deletion using the default pending window.": "This schedules the key for deletion using the default pending window.", + "This will update the current KMS configuration after key creation.": "This will update the current KMS configuration after key creation.", + "Timeout (seconds)": "Timeout (seconds)", + "Two-stage key deletion": "Two-stage key deletion", + "Use decimal values such as 384 for 0o600.": "Use decimal values such as 384 for 0o600.", + "Vault AppRole is not supported in the first version of this console.": "Vault AppRole is not supported in the first version of this console.", + "Vault Namespace": "Vault Namespace", + "Vault token authentication only": "Vault token authentication only", + "View Details": "View Details" } diff --git a/i18n/locales/es-ES.json b/i18n/locales/es-ES.json index e1216e9d..76ab31b4 100644 --- a/i18n/locales/es-ES.json +++ b/i18n/locales/es-ES.json @@ -910,5 +910,71 @@ "Completing SSO login...": "Completando inicio de sesión SSO...", "SSO Login Failed": "Error al iniciar sesión con SSO", "SSO Login Success": "Inicio de sesión con SSO correcto", - "SSO login failed: invalid callback": "Error al iniciar sesión con SSO: callback no válido" + "SSO login failed: invalid callback": "Error al iniciar sesión con SSO: callback no válido", + "Advanced Actions": "Acciones avanzadas", + "Choose the backend used by SSE/KMS.": "Elija el backend utilizado por SSE/KMS.", + "Clearing cache...": "Limpiando caché...", + "Configure the KMS backend, cache policy, and default SSE key.": "Configure el backend de KMS, la política de caché y la clave SSE predeterminada.", + "Create a new KMS key and optionally make it the default SSE key.": "Cree una nueva clave KMS y opcionalmente defínala como clave SSE predeterminada.", + "Default SSE Key": "Clave SSE predeterminada", + "Default SSE key updated successfully": "Clave SSE predeterminada actualizada correctamente", + "Delete Immediately": "Eliminar de inmediato", + "Delete Key Immediately": "Eliminar clave de inmediato", + "Describe the purpose of this key": "Describa el propósito de esta clave", + "Enable KMS Cache": "Habilitar caché de KMS", + "Enter an absolute path such as D:/data/kms-keys": "Introduzca una ruta absoluta, p. ej. D:/data/kms-keys", + "Enter the default SSE key ID": "Introduzca el ID de la clave SSE predeterminada", + "Failed to cancel key deletion": "No se pudo cancelar la eliminación de la clave", + "Failed to create KMS key": "No se pudo crear la clave KMS", + "Failed to force delete key": "No se pudo eliminar la clave de inmediato", + "Failed to restart KMS service": "No se pudo reiniciar el servicio KMS", + "Failed to save KMS configuration": "No se pudo guardar la configuración de KMS", + "Failed to schedule key deletion": "No se pudo programar la eliminación de la clave", + "Failed to update key status": "No se pudo actualizar el estado de la clave", + "KMS Backend": "Backend de KMS", + "KMS Key Details": "Detalles de la clave KMS", + "KMS configuration saved successfully": "Configuración de KMS guardada correctamente", + "KMS configuration updated successfully": "Configuración de KMS actualizada correctamente", + "KMS configured but not started": "KMS configurado pero no iniciado", + "KMS key created successfully": "Clave KMS creada correctamente", + "KMS service restarted successfully": "Servicio KMS reiniciado correctamente", + "KV Mount": "Montaje KV", + "Key Path Prefix": "Prefijo de ruta de clave", + "Key created but could not update the default SSE key. Save the configuration form and try again.": "Clave creada pero no se pudo actualizar la clave SSE predeterminada. Guarde el formulario de configuración e inténtelo de nuevo.", + "Key deleted immediately": "Clave eliminada de inmediato", + "Key deletion canceled successfully": "Eliminación de clave cancelada correctamente", + "Key deletion scheduled successfully": "Eliminación de clave programada correctamente", + "Keys in PendingDeletion can still be restored or deleted immediately.": "Las claves en PendingDeletion aún pueden restaurarse o eliminarse de inmediato.", + "Local Key Directory": "Directorio local de claves", + "Local filesystem": "Sistema de archivos local", + "No key details available": "No hay detalles de clave disponibles", + "Not set": "No definido", + "Optional Vault namespace": "Namespace de Vault opcional", + "Optional display name for the key": "Nombre para mostrar opcional de la clave", + "Please enter Vault transit mount path": "Introduzca la ruta de montaje de tránsito de Vault", + "Please enter an absolute local key directory path": "Introduzca una ruta absoluta al directorio local de claves", + "Reconfigure KMS": "Reconfigurar KMS", + "Reset to Current Status": "Restablecer al estado actual", + "Restart KMS": "Reiniciar KMS", + "Restore Key": "Restaurar clave", + "Schedule Deletion": "Programar eliminación", + "Schedule Key Deletion": "Programar eliminación de clave", + "Set as default SSE key": "Establecer como clave SSE predeterminada", + "Showing up to {count} keys per page": "Mostrando hasta {count} claves por página", + "Skip TLS verification": "Omitir verificación TLS", + "Start KMS to make SSE and key management available.": "Inicie KMS para habilitar SSE y la gestión de claves.", + "Stopping KMS...": "Deteniendo KMS...", + "The directory must be an absolute path on the server.": "El directorio debe ser una ruta absoluta en el servidor.", + "This key is used as the platform default for SSE-KMS.": "Esta clave se usa como predeterminada de la plataforma para SSE-KMS.", + "This permanently deletes the key immediately and cannot be undone.": "Esto elimina la clave de forma permanente e inmediata y no se puede deshacer.", + "This restores the key from the pending deletion state.": "Restaura la clave desde el estado de eliminación pendiente.", + "This schedules the key for deletion using the default pending window.": "Programa la eliminación de la clave con la ventana de espera predeterminada.", + "This will update the current KMS configuration after key creation.": "Actualizará la configuración actual de KMS tras crear la clave.", + "Timeout (seconds)": "Tiempo de espera (segundos)", + "Two-stage key deletion": "Eliminación de clave en dos etapas", + "Use decimal values such as 384 for 0o600.": "Use valores decimales, p. ej. 384 para 0o600.", + "Vault AppRole is not supported in the first version of this console.": "Vault AppRole no está soportado en la primera versión de esta consola.", + "Vault Namespace": "Namespace de Vault", + "Vault token authentication only": "Solo autenticación con token de Vault", + "View Details": "Ver detalles" } diff --git a/i18n/locales/fr-FR.json b/i18n/locales/fr-FR.json index faa124c2..8e6f69bc 100644 --- a/i18n/locales/fr-FR.json +++ b/i18n/locales/fr-FR.json @@ -912,5 +912,71 @@ "Completing SSO login...": "Finalisation de la connexion SSO...", "SSO Login Failed": "Échec de la connexion SSO", "SSO Login Success": "Connexion SSO réussie", - "SSO login failed: invalid callback": "Échec de la connexion SSO : rappel invalide" + "SSO login failed: invalid callback": "Échec de la connexion SSO : rappel invalide", + "Advanced Actions": "Actions avancées", + "Choose the backend used by SSE/KMS.": "Choisissez le backend utilisé par SSE/KMS.", + "Clearing cache...": "Vidage du cache...", + "Configure the KMS backend, cache policy, and default SSE key.": "Configurez le backend KMS, la politique de cache et la clé SSE par défaut.", + "Create a new KMS key and optionally make it the default SSE key.": "Créez une nouvelle clé KMS et définissez-la éventuellement comme clé SSE par défaut.", + "Default SSE Key": "Clé SSE par défaut", + "Default SSE key updated successfully": "Clé SSE par défaut mise à jour avec succès", + "Delete Immediately": "Supprimer immédiatement", + "Delete Key Immediately": "Supprimer la clé immédiatement", + "Describe the purpose of this key": "Décrivez l’usage de cette clé", + "Enable KMS Cache": "Activer le cache KMS", + "Enter an absolute path such as D:/data/kms-keys": "Saisissez un chemin absolu, ex. D:/data/kms-keys", + "Enter the default SSE key ID": "Saisissez l’ID de la clé SSE par défaut", + "Failed to cancel key deletion": "Échec de l’annulation de la suppression de la clé", + "Failed to create KMS key": "Échec de la création de la clé KMS", + "Failed to force delete key": "Échec de la suppression immédiate de la clé", + "Failed to restart KMS service": "Échec du redémarrage du service KMS", + "Failed to save KMS configuration": "Échec de l’enregistrement de la configuration KMS", + "Failed to schedule key deletion": "Échec de la planification de la suppression de la clé", + "Failed to update key status": "Échec de la mise à jour du statut de la clé", + "KMS Backend": "Backend KMS", + "KMS Key Details": "Détails de la clé KMS", + "KMS configuration saved successfully": "Configuration KMS enregistrée avec succès", + "KMS configuration updated successfully": "Configuration KMS mise à jour avec succès", + "KMS configured but not started": "KMS configuré mais non démarré", + "KMS key created successfully": "Clé KMS créée avec succès", + "KMS service restarted successfully": "Service KMS redémarré avec succès", + "KV Mount": "Montage KV", + "Key Path Prefix": "Préfixe du chemin de clé", + "Key created but could not update the default SSE key. Save the configuration form and try again.": "Clé créée mais impossible de mettre à jour la clé SSE par défaut. Enregistrez le formulaire de configuration et réessayez.", + "Key deleted immediately": "Clé supprimée immédiatement", + "Key deletion canceled successfully": "Suppression de la clé annulée avec succès", + "Key deletion scheduled successfully": "Suppression de la clé planifiée avec succès", + "Keys in PendingDeletion can still be restored or deleted immediately.": "Les clés en PendingDeletion peuvent encore être restaurées ou supprimées immédiatement.", + "Local Key Directory": "Répertoire local des clés", + "Local filesystem": "Système de fichiers local", + "No key details available": "Aucun détail de clé disponible", + "Not set": "Non défini", + "Optional Vault namespace": "Espace de noms Vault facultatif", + "Optional display name for the key": "Nom d’affichage facultatif pour la clé", + "Please enter Vault transit mount path": "Saisissez le chemin de montage transit Vault", + "Please enter an absolute local key directory path": "Saisissez un chemin absolu vers le répertoire local des clés", + "Reconfigure KMS": "Reconfigurer KMS", + "Reset to Current Status": "Réinitialiser à l’état actuel", + "Restart KMS": "Redémarrer KMS", + "Restore Key": "Restaurer la clé", + "Schedule Deletion": "Planifier la suppression", + "Schedule Key Deletion": "Planifier la suppression de la clé", + "Set as default SSE key": "Définir comme clé SSE par défaut", + "Showing up to {count} keys per page": "Jusqu’à {count} clés par page", + "Skip TLS verification": "Ignorer la vérification TLS", + "Start KMS to make SSE and key management available.": "Démarrez KMS pour activer SSE et la gestion des clés.", + "Stopping KMS...": "Arrêt de KMS...", + "The directory must be an absolute path on the server.": "Le répertoire doit être un chemin absolu sur le serveur.", + "This key is used as the platform default for SSE-KMS.": "Cette clé est utilisée par défaut sur la plateforme pour SSE-KMS.", + "This permanently deletes the key immediately and cannot be undone.": "Supprime définitivement la clé immédiatement, sans retour en arrière.", + "This restores the key from the pending deletion state.": "Restaure la clé depuis l’état de suppression en attente.", + "This schedules the key for deletion using the default pending window.": "Planifie la suppression de la clé avec la fenêtre d’attente par défaut.", + "This will update the current KMS configuration after key creation.": "Met à jour la configuration KMS actuelle après la création de la clé.", + "Timeout (seconds)": "Délai d’expiration (secondes)", + "Two-stage key deletion": "Suppression de clé en deux étapes", + "Use decimal values such as 384 for 0o600.": "Utilisez des valeurs décimales, ex. 384 pour 0o600.", + "Vault AppRole is not supported in the first version of this console.": "Vault AppRole n’est pas pris en charge dans la première version de cette console.", + "Vault Namespace": "Espace de noms Vault", + "Vault token authentication only": "Authentification par jeton Vault uniquement", + "View Details": "Voir les détails" } diff --git a/i18n/locales/id-ID.json b/i18n/locales/id-ID.json index cca0798d..641d4420 100644 --- a/i18n/locales/id-ID.json +++ b/i18n/locales/id-ID.json @@ -910,5 +910,71 @@ "Completing SSO login...": "Menyelesaikan login SSO...", "SSO Login Failed": "Login SSO gagal", "SSO Login Success": "Login SSO berhasil", - "SSO login failed: invalid callback": "Login SSO gagal: callback tidak valid" + "SSO login failed: invalid callback": "Login SSO gagal: callback tidak valid", + "Advanced Actions": "Tindakan lanjutan", + "Choose the backend used by SSE/KMS.": "Pilih backend yang digunakan SSE/KMS.", + "Clearing cache...": "Mengosongkan cache...", + "Configure the KMS backend, cache policy, and default SSE key.": "Konfigurasikan backend KMS, kebijakan cache, dan kunci SSE default.", + "Create a new KMS key and optionally make it the default SSE key.": "Buat kunci KMS baru dan opsional jadikan kunci SSE default.", + "Default SSE Key": "Kunci SSE default", + "Default SSE key updated successfully": "Kunci SSE default berhasil diperbarui", + "Delete Immediately": "Hapus segera", + "Delete Key Immediately": "Hapus kunci segera", + "Describe the purpose of this key": "Jelaskan tujuan kunci ini", + "Enable KMS Cache": "Aktifkan cache KMS", + "Enter an absolute path such as D:/data/kms-keys": "Masukkan path absolut, mis. D:/data/kms-keys", + "Enter the default SSE key ID": "Masukkan ID kunci SSE default", + "Failed to cancel key deletion": "Gagal membatalkan penghapusan kunci", + "Failed to create KMS key": "Gagal membuat kunci KMS", + "Failed to force delete key": "Gagal menghapus kunci segera", + "Failed to restart KMS service": "Gagal memulai ulang layanan KMS", + "Failed to save KMS configuration": "Gagal menyimpan konfigurasi KMS", + "Failed to schedule key deletion": "Gagal menjadwalkan penghapusan kunci", + "Failed to update key status": "Gagal memperbarui status kunci", + "KMS Backend": "Backend KMS", + "KMS Key Details": "Detail kunci KMS", + "KMS configuration saved successfully": "Konfigurasi KMS berhasil disimpan", + "KMS configuration updated successfully": "Konfigurasi KMS berhasil diperbarui", + "KMS configured but not started": "KMS dikonfigurasi tetapi belum dijalankan", + "KMS key created successfully": "Kunci KMS berhasil dibuat", + "KMS service restarted successfully": "Layanan KMS berhasil dimulai ulang", + "KV Mount": "Mount KV", + "Key Path Prefix": "Awalan path kunci", + "Key created but could not update the default SSE key. Save the configuration form and try again.": "Kunci dibuat tetapi tidak dapat memperbarui kunci SSE default. Simpan formulir konfigurasi lalu coba lagi.", + "Key deleted immediately": "Kunci dihapus segera", + "Key deletion canceled successfully": "Penghapusan kunci berhasil dibatalkan", + "Key deletion scheduled successfully": "Penghapusan kunci berhasil dijadwalkan", + "Keys in PendingDeletion can still be restored or deleted immediately.": "Kunci dalam PendingDeletion masih dapat dipulihkan atau dihapus segera.", + "Local Key Directory": "Direktori kunci lokal", + "Local filesystem": "Sistem file lokal", + "No key details available": "Tidak ada detail kunci", + "Not set": "Belum diatur", + "Optional Vault namespace": "Namespace Vault opsional", + "Optional display name for the key": "Nama tampilan kunci opsional", + "Please enter Vault transit mount path": "Masukkan path mount transit Vault", + "Please enter an absolute local key directory path": "Masukkan path absolut ke direktori kunci lokal", + "Reconfigure KMS": "Konfigurasi ulang KMS", + "Reset to Current Status": "Setel ulang ke status saat ini", + "Restart KMS": "Mulai ulang KMS", + "Restore Key": "Pulihkan kunci", + "Schedule Deletion": "Jadwalkan penghapusan", + "Schedule Key Deletion": "Jadwalkan penghapusan kunci", + "Set as default SSE key": "Jadikan kunci SSE default", + "Showing up to {count} keys per page": "Menampilkan hingga {count} kunci per halaman", + "Skip TLS verification": "Lewati verifikasi TLS", + "Start KMS to make SSE and key management available.": "Jalankan KMS untuk mengaktifkan SSE dan pengelolaan kunci.", + "Stopping KMS...": "Menghentikan KMS...", + "The directory must be an absolute path on the server.": "Direktori harus berupa path absolut di server.", + "This key is used as the platform default for SSE-KMS.": "Kunci ini digunakan sebagai default platform untuk SSE-KMS.", + "This permanently deletes the key immediately and cannot be undone.": "Menghapus kunci secara permanen segera dan tidak dapat dibatalkan.", + "This restores the key from the pending deletion state.": "Memulihkan kunci dari status penghapusan tertunda.", + "This schedules the key for deletion using the default pending window.": "Menjadwalkan penghapusan kunci dengan jendela tunggu default.", + "This will update the current KMS configuration after key creation.": "Memperbarui konfigurasi KMS saat ini setelah kunci dibuat.", + "Timeout (seconds)": "Batas waktu (detik)", + "Two-stage key deletion": "Penghapusan kunci dua tahap", + "Use decimal values such as 384 for 0o600.": "Gunakan nilai desimal, mis. 384 untuk 0o600.", + "Vault AppRole is not supported in the first version of this console.": "Vault AppRole tidak didukung pada versi pertama konsol ini.", + "Vault Namespace": "Namespace Vault", + "Vault token authentication only": "Hanya autentikasi token Vault", + "View Details": "Lihat detail" } diff --git a/i18n/locales/it-IT.json b/i18n/locales/it-IT.json index 5146a1e2..8eddf3c1 100644 --- a/i18n/locales/it-IT.json +++ b/i18n/locales/it-IT.json @@ -911,5 +911,71 @@ "Completing SSO login...": "Completamento dell'accesso SSO...", "SSO Login Failed": "Accesso SSO non riuscito", "SSO Login Success": "Accesso SSO riuscito", - "SSO login failed: invalid callback": "Accesso SSO non riuscito: callback non valido" + "SSO login failed: invalid callback": "Accesso SSO non riuscito: callback non valido", + "Advanced Actions": "Azioni avanzate", + "Choose the backend used by SSE/KMS.": "Scegli il backend utilizzato da SSE/KMS.", + "Clearing cache...": "Svuotamento cache in corso...", + "Configure the KMS backend, cache policy, and default SSE key.": "Configura backend KMS, policy della cache e chiave SSE predefinita.", + "Create a new KMS key and optionally make it the default SSE key.": "Crea una nuova chiave KMS e impostala facoltativamente come chiave SSE predefinita.", + "Default SSE Key": "Chiave SSE predefinita", + "Default SSE key updated successfully": "Chiave SSE predefinita aggiornata correttamente", + "Delete Immediately": "Elimina immediatamente", + "Delete Key Immediately": "Elimina chiave immediatamente", + "Describe the purpose of this key": "Descrivi lo scopo di questa chiave", + "Enable KMS Cache": "Abilita cache KMS", + "Enter an absolute path such as D:/data/kms-keys": "Inserisci un percorso assoluto, ad es. D:/data/kms-keys", + "Enter the default SSE key ID": "Inserisci l’ID della chiave SSE predefinita", + "Failed to cancel key deletion": "Impossibile annullare l’eliminazione della chiave", + "Failed to create KMS key": "Impossibile creare la chiave KMS", + "Failed to force delete key": "Impossibile eliminare immediatamente la chiave", + "Failed to restart KMS service": "Impossibile riavviare il servizio KMS", + "Failed to save KMS configuration": "Impossibile salvare la configurazione KMS", + "Failed to schedule key deletion": "Impossibile pianificare l’eliminazione della chiave", + "Failed to update key status": "Impossibile aggiornare lo stato della chiave", + "KMS Backend": "Backend KMS", + "KMS Key Details": "Dettagli chiave KMS", + "KMS configuration saved successfully": "Configurazione KMS salvata correttamente", + "KMS configuration updated successfully": "Configurazione KMS aggiornata correttamente", + "KMS configured but not started": "KMS configurato ma non avviato", + "KMS key created successfully": "Chiave KMS creata correttamente", + "KMS service restarted successfully": "Servizio KMS riavviato correttamente", + "KV Mount": "Mount KV", + "Key Path Prefix": "Prefisso percorso chiave", + "Key created but could not update the default SSE key. Save the configuration form and try again.": "Chiave creata ma impossibile aggiornare la chiave SSE predefinita. Salva il modulo di configurazione e riprova.", + "Key deleted immediately": "Chiave eliminata immediatamente", + "Key deletion canceled successfully": "Eliminazione chiave annullata correttamente", + "Key deletion scheduled successfully": "Eliminazione chiave pianificata correttamente", + "Keys in PendingDeletion can still be restored or deleted immediately.": "Le chiavi in PendingDeletion possono ancora essere ripristinate o eliminate immediatamente.", + "Local Key Directory": "Directory locale chiavi", + "Local filesystem": "File system locale", + "No key details available": "Nessun dettaglio chiave disponibile", + "Not set": "Non impostato", + "Optional Vault namespace": "Namespace Vault facoltativo", + "Optional display name for the key": "Nome visualizzato facoltativo per la chiave", + "Please enter Vault transit mount path": "Inserisci il percorso di mount transit Vault", + "Please enter an absolute local key directory path": "Inserisci un percorso assoluto alla directory locale delle chiavi", + "Reconfigure KMS": "Riconfigura KMS", + "Reset to Current Status": "Ripristina allo stato attuale", + "Restart KMS": "Riavvia KMS", + "Restore Key": "Ripristina chiave", + "Schedule Deletion": "Pianifica eliminazione", + "Schedule Key Deletion": "Pianifica eliminazione chiave", + "Set as default SSE key": "Imposta come chiave SSE predefinita", + "Showing up to {count} keys per page": "Fino a {count} chiavi per pagina", + "Skip TLS verification": "Salta verifica TLS", + "Start KMS to make SSE and key management available.": "Avvia KMS per abilitare SSE e la gestione delle chiavi.", + "Stopping KMS...": "Arresto KMS in corso...", + "The directory must be an absolute path on the server.": "La directory deve essere un percorso assoluto sul server.", + "This key is used as the platform default for SSE-KMS.": "Questa chiave è il predefinito della piattaforma per SSE-KMS.", + "This permanently deletes the key immediately and cannot be undone.": "Elimina definitivamente la chiave immediatamente e non può essere annullato.", + "This restores the key from the pending deletion state.": "Ripristina la chiave dallo stato di eliminazione in sospeso.", + "This schedules the key for deletion using the default pending window.": "Pianifica l’eliminazione della chiave con la finestra di attesa predefinita.", + "This will update the current KMS configuration after key creation.": "Aggiorna la configurazione KMS corrente dopo la creazione della chiave.", + "Timeout (seconds)": "Timeout (secondi)", + "Two-stage key deletion": "Eliminazione chiave in due fasi", + "Use decimal values such as 384 for 0o600.": "Usa valori decimali, ad es. 384 per 0o600.", + "Vault AppRole is not supported in the first version of this console.": "Vault AppRole non è supportato nella prima versione di questa console.", + "Vault Namespace": "Namespace Vault", + "Vault token authentication only": "Solo autenticazione con token Vault", + "View Details": "Visualizza dettagli" } diff --git a/i18n/locales/ja-JP.json b/i18n/locales/ja-JP.json index eea2a445..26298547 100644 --- a/i18n/locales/ja-JP.json +++ b/i18n/locales/ja-JP.json @@ -907,5 +907,71 @@ "Completing SSO login...": "SSO ログインを完了しています...", "SSO Login Failed": "SSO ログインに失敗しました", "SSO Login Success": "SSO ログインに成功しました", - "SSO login failed: invalid callback": "SSO ログインに失敗しました: コールバックが無効です" + "SSO login failed: invalid callback": "SSO ログインに失敗しました: コールバックが無効です", + "Advanced Actions": "詳細操作", + "Choose the backend used by SSE/KMS.": "SSE/KMS で使用するバックエンドを選択します。", + "Clearing cache...": "キャッシュをクリアしています...", + "Configure the KMS backend, cache policy, and default SSE key.": "KMS バックエンド、キャッシュポリシー、デフォルト SSE キーを設定します。", + "Create a new KMS key and optionally make it the default SSE key.": "新しい KMS キーを作成し、必要に応じてデフォルト SSE キーに設定します。", + "Default SSE Key": "デフォルト SSE キー", + "Default SSE key updated successfully": "デフォルト SSE キーを更新しました", + "Delete Immediately": "すぐに削除", + "Delete Key Immediately": "キーをすぐに削除", + "Describe the purpose of this key": "このキーの用途を説明", + "Enable KMS Cache": "KMS キャッシュを有効にする", + "Enter an absolute path such as D:/data/kms-keys": "絶対パスを入力(例: D:/data/kms-keys)", + "Enter the default SSE key ID": "デフォルト SSE キー ID を入力", + "Failed to cancel key deletion": "キー削除の取り消しに失敗しました", + "Failed to create KMS key": "KMS キーの作成に失敗しました", + "Failed to force delete key": "キーの即時削除に失敗しました", + "Failed to restart KMS service": "KMS サービスの再起動に失敗しました", + "Failed to save KMS configuration": "KMS 設定の保存に失敗しました", + "Failed to schedule key deletion": "キー削除のスケジュールに失敗しました", + "Failed to update key status": "キー状態の更新に失敗しました", + "KMS Backend": "KMS バックエンド", + "KMS Key Details": "KMS キー詳細", + "KMS configuration saved successfully": "KMS 設定を保存しました", + "KMS configuration updated successfully": "KMS 設定を更新しました", + "KMS configured but not started": "KMS は設定済みですが未起動です", + "KMS key created successfully": "KMS キーを作成しました", + "KMS service restarted successfully": "KMS サービスを再起動しました", + "KV Mount": "KV マウント", + "Key Path Prefix": "キー パス プレフィックス", + "Key created but could not update the default SSE key. Save the configuration form and try again.": "キーは作成されましたが、デフォルト SSE キーを更新できませんでした。設定フォームを保存してから再試行してください。", + "Key deleted immediately": "キーを即時削除しました", + "Key deletion canceled successfully": "キー削除を取り消しました", + "Key deletion scheduled successfully": "キー削除をスケジュールしました", + "Keys in PendingDeletion can still be restored or deleted immediately.": "PendingDeletion のキーは復元または即時削除が可能です。", + "Local Key Directory": "ローカルキー ディレクトリ", + "Local filesystem": "ローカルファイルシステム", + "No key details available": "キー詳細が利用できません", + "Not set": "未設定", + "Optional Vault namespace": "任意の Vault ネームスペース", + "Optional display name for the key": "キーの表示名(任意)", + "Please enter Vault transit mount path": "Vault transit のマウントパスを入力してください", + "Please enter an absolute local key directory path": "ローカルキー ディレクトリの絶対パスを入力してください", + "Reconfigure KMS": "KMS を再構成", + "Reset to Current Status": "現在の状態にリセット", + "Restart KMS": "KMS を再起動", + "Restore Key": "キーを復元", + "Schedule Deletion": "削除をスケジュール", + "Schedule Key Deletion": "キー削除をスケジュール", + "Set as default SSE key": "デフォルト SSE キーに設定", + "Showing up to {count} keys per page": "1 ページあたり最大 {count} 件のキー", + "Skip TLS verification": "TLS 検証をスキップ", + "Start KMS to make SSE and key management available.": "SSE とキー管理を利用するには KMS を起動してください。", + "Stopping KMS...": "KMS を停止しています...", + "The directory must be an absolute path on the server.": "ディレクトリはサーバー上の絶対パスである必要があります。", + "This key is used as the platform default for SSE-KMS.": "このキーはプラットフォームの SSE-KMS デフォルトとして使用されます。", + "This permanently deletes the key immediately and cannot be undone.": "キーをすぐに完全削除します。元に戻せません。", + "This restores the key from the pending deletion state.": "削除待ち状態からキーを復元します。", + "This schedules the key for deletion using the default pending window.": "デフォルトの待機期間でキー削除をスケジュールします。", + "This will update the current KMS configuration after key creation.": "キー作成後に現在の KMS 設定を更新します。", + "Timeout (seconds)": "タイムアウト(秒)", + "Two-stage key deletion": "二段階キー削除", + "Use decimal values such as 384 for 0o600.": "10 進数で入力(例: 384 は 0o600)", + "Vault AppRole is not supported in the first version of this console.": "このコンソールの初版では Vault AppRole はサポートしていません。", + "Vault Namespace": "Vault ネームスペース", + "Vault token authentication only": "Vault トークン認証のみ", + "View Details": "詳細を表示" } diff --git a/i18n/locales/ko-KR.json b/i18n/locales/ko-KR.json index 81a7470c..0b1ba671 100644 --- a/i18n/locales/ko-KR.json +++ b/i18n/locales/ko-KR.json @@ -907,5 +907,71 @@ "Completing SSO login...": "SSO 로그인을 완료하는 중...", "SSO Login Failed": "SSO 로그인 실패", "SSO Login Success": "SSO 로그인 성공", - "SSO login failed: invalid callback": "SSO 로그인 실패: 잘못된 콜백" + "SSO login failed: invalid callback": "SSO 로그인 실패: 잘못된 콜백", + "Advanced Actions": "고급 작업", + "Choose the backend used by SSE/KMS.": "SSE/KMS에서 사용할 백엔드를 선택합니다.", + "Clearing cache...": "캐시를 비우는 중...", + "Configure the KMS backend, cache policy, and default SSE key.": "KMS 백엔드, 캐시 정책 및 기본 SSE 키를 구성합니다.", + "Create a new KMS key and optionally make it the default SSE key.": "새 KMS 키를 만들고 필요하면 기본 SSE 키로 설정합니다.", + "Default SSE Key": "기본 SSE 키", + "Default SSE key updated successfully": "기본 SSE 키가 업데이트되었습니다", + "Delete Immediately": "즉시 삭제", + "Delete Key Immediately": "키 즉시 삭제", + "Describe the purpose of this key": "이 키의 용도를 설명하세요", + "Enable KMS Cache": "KMS 캐시 사용", + "Enter an absolute path such as D:/data/kms-keys": "절대 경로 예: D:/data/kms-keys", + "Enter the default SSE key ID": "기본 SSE 키 ID 입력", + "Failed to cancel key deletion": "키 삭제 취소에 실패했습니다", + "Failed to create KMS key": "KMS 키 생성에 실패했습니다", + "Failed to force delete key": "키 즉시 삭제에 실패했습니다", + "Failed to restart KMS service": "KMS 서비스 재시작에 실패했습니다", + "Failed to save KMS configuration": "KMS 구성 저장에 실패했습니다", + "Failed to schedule key deletion": "키 삭제 예약에 실패했습니다", + "Failed to update key status": "키 상태 업데이트에 실패했습니다", + "KMS Backend": "KMS 백엔드", + "KMS Key Details": "KMS 키 세부 정보", + "KMS configuration saved successfully": "KMS 구성이 저장되었습니다", + "KMS configuration updated successfully": "KMS 구성이 업데이트되었습니다", + "KMS configured but not started": "KMS는 구성되었으나 시작되지 않음", + "KMS key created successfully": "KMS 키가 생성되었습니다", + "KMS service restarted successfully": "KMS 서비스가 재시작되었습니다", + "KV Mount": "KV 마운트", + "Key Path Prefix": "키 경로 접두사", + "Key created but could not update the default SSE key. Save the configuration form and try again.": "키는 생성되었으나 기본 SSE 키를 업데이트할 수 없습니다. 구성 양식을 저장한 후 다시 시도하세요.", + "Key deleted immediately": "키가 즉시 삭제되었습니다", + "Key deletion canceled successfully": "키 삭제가 취소되었습니다", + "Key deletion scheduled successfully": "키 삭제가 예약되었습니다", + "Keys in PendingDeletion can still be restored or deleted immediately.": "PendingDeletion 상태의 키는 복원하거나 즉시 삭제할 수 있습니다.", + "Local Key Directory": "로컬 키 디렉터리", + "Local filesystem": "로컬 파일 시스템", + "No key details available": "키 세부 정보를 사용할 수 없습니다", + "Not set": "설정되지 않음", + "Optional Vault namespace": "선택 Vault 네임스페이스", + "Optional display name for the key": "키 표시 이름(선택)", + "Please enter Vault transit mount path": "Vault transit 마운트 경로를 입력하세요", + "Please enter an absolute local key directory path": "로컬 키 디렉터리의 절대 경로를 입력하세요", + "Reconfigure KMS": "KMS 재구성", + "Reset to Current Status": "현재 상태로 복원", + "Restart KMS": "KMS 재시작", + "Restore Key": "키 복원", + "Schedule Deletion": "삭제 예약", + "Schedule Key Deletion": "키 삭제 예약", + "Set as default SSE key": "기본 SSE 키로 설정", + "Showing up to {count} keys per page": "페이지당 최대 {count}개 키", + "Skip TLS verification": "TLS 검증 건너뛰기", + "Start KMS to make SSE and key management available.": "SSE 및 키 관리를 사용하려면 KMS를 시작하세요.", + "Stopping KMS...": "KMS 중지 중...", + "The directory must be an absolute path on the server.": "디렉터리는 서버의 절대 경로여야 합니다.", + "This key is used as the platform default for SSE-KMS.": "이 키는 플랫폼의 SSE-KMS 기본값으로 사용됩니다.", + "This permanently deletes the key immediately and cannot be undone.": "키를 즉시 영구 삭제하며 되돌릴 수 없습니다.", + "This restores the key from the pending deletion state.": "삭제 대기 상태에서 키를 복원합니다.", + "This schedules the key for deletion using the default pending window.": "기본 대기 기간으로 키 삭제를 예약합니다.", + "This will update the current KMS configuration after key creation.": "키 생성 후 현재 KMS 구성을 업데이트합니다.", + "Timeout (seconds)": "Timeout (초)", + "Two-stage key deletion": "2단계 키 삭제", + "Use decimal values such as 384 for 0o600.": "10진수 값(예: 384는 0o600)을 사용하세요.", + "Vault AppRole is not supported in the first version of this console.": "이 콘솔 첫 버전에서는 Vault AppRole을 지원하지 않습니다.", + "Vault Namespace": "Vault 네임스페이스", + "Vault token authentication only": "Vault 토큰 인증만", + "View Details": "세부 정보 보기" } diff --git a/i18n/locales/pt-BR.json b/i18n/locales/pt-BR.json index 211e55a6..32470e91 100644 --- a/i18n/locales/pt-BR.json +++ b/i18n/locales/pt-BR.json @@ -911,5 +911,71 @@ "Completing SSO login...": "Concluindo login SSO...", "SSO Login Failed": "Falha no login SSO", "SSO Login Success": "Login SSO realizado com sucesso", - "SSO login failed: invalid callback": "Falha no login SSO: callback inválido" + "SSO login failed: invalid callback": "Falha no login SSO: callback inválido", + "Advanced Actions": "Ações avançadas", + "Choose the backend used by SSE/KMS.": "Escolha o backend usado pelo SSE/KMS.", + "Clearing cache...": "Limpando cache...", + "Configure the KMS backend, cache policy, and default SSE key.": "Configure o backend KMS, a política de cache e a chave SSE padrão.", + "Create a new KMS key and optionally make it the default SSE key.": "Crie uma nova chave KMS e defina-a opcionalmente como chave SSE padrão.", + "Default SSE Key": "Chave SSE padrão", + "Default SSE key updated successfully": "Chave SSE padrão atualizada com sucesso", + "Delete Immediately": "Excluir imediatamente", + "Delete Key Immediately": "Excluir chave imediatamente", + "Describe the purpose of this key": "Descreva o propósito desta chave", + "Enable KMS Cache": "Habilitar cache KMS", + "Enter an absolute path such as D:/data/kms-keys": "Informe um caminho absoluto, ex.: D:/data/kms-keys", + "Enter the default SSE key ID": "Informe o ID da chave SSE padrão", + "Failed to cancel key deletion": "Falha ao cancelar a exclusão da chave", + "Failed to create KMS key": "Falha ao criar a chave KMS", + "Failed to force delete key": "Falha ao excluir a chave imediatamente", + "Failed to restart KMS service": "Falha ao reiniciar o serviço KMS", + "Failed to save KMS configuration": "Falha ao salvar a configuração KMS", + "Failed to schedule key deletion": "Falha ao agendar a exclusão da chave", + "Failed to update key status": "Falha ao atualizar o status da chave", + "KMS Backend": "Backend KMS", + "KMS Key Details": "Detalhes da chave KMS", + "KMS configuration saved successfully": "Configuração KMS salva com sucesso", + "KMS configuration updated successfully": "Configuração KMS atualizada com sucesso", + "KMS configured but not started": "KMS configurado, mas não iniciado", + "KMS key created successfully": "Chave KMS criada com sucesso", + "KMS service restarted successfully": "Serviço KMS reiniciado com sucesso", + "KV Mount": "Montagem KV", + "Key Path Prefix": "Prefixo do caminho da chave", + "Key created but could not update the default SSE key. Save the configuration form and try again.": "Chave criada, mas não foi possível atualizar a chave SSE padrão. Salve o formulário de configuração e tente novamente.", + "Key deleted immediately": "Chave excluída imediatamente", + "Key deletion canceled successfully": "Exclusão da chave cancelada com sucesso", + "Key deletion scheduled successfully": "Exclusão da chave agendada com sucesso", + "Keys in PendingDeletion can still be restored or deleted immediately.": "Chaves em PendingDeletion ainda podem ser restauradas ou excluídas imediatamente.", + "Local Key Directory": "Diretório local de chaves", + "Local filesystem": "Sistema de arquivos local", + "No key details available": "Nenhum detalhe de chave disponível", + "Not set": "Não definido", + "Optional Vault namespace": "Namespace Vault opcional", + "Optional display name for the key": "Nome de exibição opcional da chave", + "Please enter Vault transit mount path": "Informe o caminho de montagem transit do Vault", + "Please enter an absolute local key directory path": "Informe um caminho absoluto para o diretório local de chaves", + "Reconfigure KMS": "Reconfigurar KMS", + "Reset to Current Status": "Redefinir para o status atual", + "Restart KMS": "Reiniciar KMS", + "Restore Key": "Restaurar chave", + "Schedule Deletion": "Agendar exclusão", + "Schedule Key Deletion": "Agendar exclusão da chave", + "Set as default SSE key": "Definir como chave SSE padrão", + "Showing up to {count} keys per page": "Mostrando até {count} chaves por página", + "Skip TLS verification": "Ignorar verificação TLS", + "Start KMS to make SSE and key management available.": "Inicie o KMS para habilitar SSE e o gerenciamento de chaves.", + "Stopping KMS...": "Parando KMS...", + "The directory must be an absolute path on the server.": "O diretório deve ser um caminho absoluto no servidor.", + "This key is used as the platform default for SSE-KMS.": "Esta chave é usada como padrão da plataforma para SSE-KMS.", + "This permanently deletes the key immediately and cannot be undone.": "Exclui a chave permanentemente de imediato e não pode ser desfeito.", + "This restores the key from the pending deletion state.": "Restaura a chave do estado de exclusão pendente.", + "This schedules the key for deletion using the default pending window.": "Agenda a exclusão da chave com a janela de espera padrão.", + "This will update the current KMS configuration after key creation.": "Atualiza a configuração KMS atual após a criação da chave.", + "Timeout (seconds)": "Tempo limite (segundos)", + "Two-stage key deletion": "Exclusão de chave em duas etapas", + "Use decimal values such as 384 for 0o600.": "Use valores decimais, ex.: 384 para 0o600.", + "Vault AppRole is not supported in the first version of this console.": "Vault AppRole não é suportado na primeira versão deste console.", + "Vault Namespace": "Namespace Vault", + "Vault token authentication only": "Somente autenticação por token Vault", + "View Details": "Ver detalhes" } diff --git a/i18n/locales/ru-RU.json b/i18n/locales/ru-RU.json index f302a60f..4d4d0f96 100644 --- a/i18n/locales/ru-RU.json +++ b/i18n/locales/ru-RU.json @@ -912,5 +912,71 @@ "Completing SSO login...": "Завершение входа через SSO...", "SSO Login Failed": "Ошибка входа через SSO", "SSO Login Success": "Вход через SSO выполнен успешно", - "SSO login failed: invalid callback": "Ошибка входа через SSO: недопустимый callback" + "SSO login failed: invalid callback": "Ошибка входа через SSO: недопустимый callback", + "Advanced Actions": "Дополнительные действия", + "Choose the backend used by SSE/KMS.": "Выберите бэкенд для SSE/KMS.", + "Clearing cache...": "Очистка кэша...", + "Configure the KMS backend, cache policy, and default SSE key.": "Настройте бэкенд KMS, политику кэша и ключ SSE по умолчанию.", + "Create a new KMS key and optionally make it the default SSE key.": "Создайте новый ключ KMS и при необходимости сделайте его ключом SSE по умолчанию.", + "Default SSE Key": "Ключ SSE по умолчанию", + "Default SSE key updated successfully": "Ключ SSE по умолчанию успешно обновлён", + "Delete Immediately": "Удалить немедленно", + "Delete Key Immediately": "Немедленно удалить ключ", + "Describe the purpose of this key": "Опишите назначение этого ключа", + "Enable KMS Cache": "Включить кэш KMS", + "Enter an absolute path such as D:/data/kms-keys": "Введите абсолютный путь, например D:/data/kms-keys", + "Enter the default SSE key ID": "Введите ID ключа SSE по умолчанию", + "Failed to cancel key deletion": "Не удалось отменить удаление ключа", + "Failed to create KMS key": "Не удалось создать ключ KMS", + "Failed to force delete key": "Не удалось немедленно удалить ключ", + "Failed to restart KMS service": "Не удалось перезапустить службу KMS", + "Failed to save KMS configuration": "Не удалось сохранить конфигурацию KMS", + "Failed to schedule key deletion": "Не удалось запланировать удаление ключа", + "Failed to update key status": "Не удалось обновить состояние ключа", + "KMS Backend": "Бэкенд KMS", + "KMS Key Details": "Сведения о ключе KMS", + "KMS configuration saved successfully": "Конфигурация KMS успешно сохранена", + "KMS configuration updated successfully": "Конфигурация KMS успешно обновлена", + "KMS configured but not started": "KMS настроен, но не запущен", + "KMS key created successfully": "Ключ KMS успешно создан", + "KMS service restarted successfully": "Служба KMS успешно перезапущена", + "KV Mount": "Монтирование KV", + "Key Path Prefix": "Префикс пути ключа", + "Key created but could not update the default SSE key. Save the configuration form and try again.": "Ключ создан, но не удалось обновить ключ SSE по умолчанию. Сохраните форму конфигурации и повторите попытку.", + "Key deleted immediately": "Ключ немедленно удалён", + "Key deletion canceled successfully": "Удаление ключа успешно отменено", + "Key deletion scheduled successfully": "Удаление ключа успешно запланировано", + "Keys in PendingDeletion can still be restored or deleted immediately.": "Ключи в состоянии PendingDeletion всё ещё можно восстановить или удалить немедленно.", + "Local Key Directory": "Локальный каталог ключей", + "Local filesystem": "Локальная файловая система", + "No key details available": "Сведения о ключе недоступны", + "Not set": "Не задано", + "Optional Vault namespace": "Необязательное пространство имён Vault", + "Optional display name for the key": "Необязательное отображаемое имя ключа", + "Please enter Vault transit mount path": "Введите путь монтирования transit Vault", + "Please enter an absolute local key directory path": "Введите абсолютный путь к локальному каталогу ключей", + "Reconfigure KMS": "Переконфигурировать KMS", + "Reset to Current Status": "Сбросить к текущему состоянию", + "Restart KMS": "Перезапустить KMS", + "Restore Key": "Восстановить ключ", + "Schedule Deletion": "Запланировать удаление", + "Schedule Key Deletion": "Запланировать удаление ключа", + "Set as default SSE key": "Сделать ключом SSE по умолчанию", + "Showing up to {count} keys per page": "До {count} ключей на страницу", + "Skip TLS verification": "Пропустить проверку TLS", + "Start KMS to make SSE and key management available.": "Запустите KMS, чтобы использовать SSE и управление ключами.", + "Stopping KMS...": "Остановка KMS...", + "The directory must be an absolute path on the server.": "Каталог должен быть абсолютным путём на сервере.", + "This key is used as the platform default for SSE-KMS.": "Этот ключ используется по умолчанию платформы для SSE-KMS.", + "This permanently deletes the key immediately and cannot be undone.": "Немедленно и безвозвратно удаляет ключ.", + "This restores the key from the pending deletion state.": "Восстанавливает ключ из состояния ожидающего удаления.", + "This schedules the key for deletion using the default pending window.": "Планирует удаление ключа с окном ожидания по умолчанию.", + "This will update the current KMS configuration after key creation.": "Обновит текущую конфигурацию KMS после создания ключа.", + "Timeout (seconds)": "Тайм-аут (секунды)", + "Two-stage key deletion": "Двухэтапное удаление ключа", + "Use decimal values such as 384 for 0o600.": "Используйте десятичные значения, например 384 для 0o600.", + "Vault AppRole is not supported in the first version of this console.": "Vault AppRole не поддерживается в первой версии этой консоли.", + "Vault Namespace": "Пространство имён Vault", + "Vault token authentication only": "Только аутентификация по токену Vault", + "View Details": "Подробности" } diff --git a/i18n/locales/tr-TR.json b/i18n/locales/tr-TR.json index abc1502d..2dd51d60 100644 --- a/i18n/locales/tr-TR.json +++ b/i18n/locales/tr-TR.json @@ -903,5 +903,71 @@ "Completing SSO login...": "SSO girişi tamamlanıyor...", "SSO Login Failed": "SSO girişi başarısız", "SSO Login Success": "SSO girişi başarılı", - "SSO login failed: invalid callback": "SSO girişi başarısız: geçersiz geri çağrı" + "SSO login failed: invalid callback": "SSO girişi başarısız: geçersiz geri çağrı", + "Advanced Actions": "Gelişmiş işlemler", + "Choose the backend used by SSE/KMS.": "SSE/KMS tarafından kullanılan arka ucu seçin.", + "Clearing cache...": "Önbellek temizleniyor...", + "Configure the KMS backend, cache policy, and default SSE key.": "KMS arka ucu, önbellek ilkesi ve varsayılan SSE anahtarını yapılandırın.", + "Create a new KMS key and optionally make it the default SSE key.": "Yeni bir KMS anahtarı oluşturun ve isteğe bağlı olarak varsayılan SSE anahtarı yapın.", + "Default SSE Key": "Varsayılan SSE anahtarı", + "Default SSE key updated successfully": "Varsayılan SSE anahtarı güncellendi", + "Delete Immediately": "Hemen sil", + "Delete Key Immediately": "Anahtarı hemen sil", + "Describe the purpose of this key": "Bu anahtarın amacını açıklayın", + "Enable KMS Cache": "KMS önbelleğini etkinleştir", + "Enter an absolute path such as D:/data/kms-keys": "Mutlak yol girin, örn. D:/data/kms-keys", + "Enter the default SSE key ID": "Varsayılan SSE anahtar kimliğini girin", + "Failed to cancel key deletion": "Anahtar silme iptal edilemedi", + "Failed to create KMS key": "KMS anahtarı oluşturulamadı", + "Failed to force delete key": "Anahtar hemen silinemedi", + "Failed to restart KMS service": "KMS hizmeti yeniden başlatılamadı", + "Failed to save KMS configuration": "KMS yapılandırması kaydedilemedi", + "Failed to schedule key deletion": "Anahtar silme planlanamadı", + "Failed to update key status": "Anahtar durumu güncellenemedi", + "KMS Backend": "KMS arka ucu", + "KMS Key Details": "KMS anahtar ayrıntıları", + "KMS configuration saved successfully": "KMS yapılandırması kaydedildi", + "KMS configuration updated successfully": "KMS yapılandırması güncellendi", + "KMS configured but not started": "KMS yapılandırıldı ancak başlatılmadı", + "KMS key created successfully": "KMS anahtarı oluşturuldu", + "KMS service restarted successfully": "KMS hizmeti yeniden başlatıldı", + "KV Mount": "KV bağlama", + "Key Path Prefix": "Anahtar yolu öneki", + "Key created but could not update the default SSE key. Save the configuration form and try again.": "Anahtar oluşturuldu ancak varsayılan SSE anahtarı güncellenemedi. Yapılandırma formunu kaydedip tekrar deneyin.", + "Key deleted immediately": "Anahtar hemen silindi", + "Key deletion canceled successfully": "Anahtar silme iptal edildi", + "Key deletion scheduled successfully": "Anahtar silme planlandı", + "Keys in PendingDeletion can still be restored or deleted immediately.": "PendingDeletion durumundaki anahtarlar hâlâ geri yüklenebilir veya hemen silinebilir.", + "Local Key Directory": "Yerel anahtar dizini", + "Local filesystem": "Yerel dosya sistemi", + "No key details available": "Anahtar ayrıntısı yok", + "Not set": "Ayarlanmadı", + "Optional Vault namespace": "İsteğe bağlı Vault ad alanı", + "Optional display name for the key": "Anahtar için isteğe bağlı görünen ad", + "Please enter Vault transit mount path": "Vault transit bağlama yolunu girin", + "Please enter an absolute local key directory path": "Yerel anahtar dizinine mutlak yol girin", + "Reconfigure KMS": "KMS’yi yeniden yapılandır", + "Reset to Current Status": "Geçerli duruma sıfırla", + "Restart KMS": "KMS’yi yeniden başlat", + "Restore Key": "Anahtarı geri yükle", + "Schedule Deletion": "Silme planla", + "Schedule Key Deletion": "Anahtar silme planla", + "Set as default SSE key": "Varsayılan SSE anahtarı yap", + "Showing up to {count} keys per page": "Sayfa başına en fazla {count} anahtar", + "Skip TLS verification": "TLS doğrulamasını atla", + "Start KMS to make SSE and key management available.": "SSE ve anahtar yönetimini kullanmak için KMS’yi başlatın.", + "Stopping KMS...": "KMS durduruluyor...", + "The directory must be an absolute path on the server.": "Dizin sunucuda mutlak yol olmalıdır.", + "This key is used as the platform default for SSE-KMS.": "Bu anahtar platformun SSE-KMS varsayılanıdır.", + "This permanently deletes the key immediately and cannot be undone.": "Anahtarı hemen kalıcı olarak siler ve geri alınamaz.", + "This restores the key from the pending deletion state.": "Anahtarı bekleyen silme durumundan geri yükler.", + "This schedules the key for deletion using the default pending window.": "Varsayılan bekleme süresiyle silmeyi planlar.", + "This will update the current KMS configuration after key creation.": "Anahtar oluşturulduktan sonra geçerli KMS yapılandırmasını günceller.", + "Timeout (seconds)": "Zaman aşımı (saniye)", + "Two-stage key deletion": "İki aşamalı anahtar silme", + "Use decimal values such as 384 for 0o600.": "Ondalık değer kullanın, örn. 384 için 0o600.", + "Vault AppRole is not supported in the first version of this console.": "Vault AppRole bu konsolun ilk sürümünde desteklenmez.", + "Vault Namespace": "Vault ad alanı", + "Vault token authentication only": "Yalnızca Vault token kimlik doğrulaması", + "View Details": "Ayrıntıları göster" } diff --git a/i18n/locales/vi-VN.json b/i18n/locales/vi-VN.json index f496c9f4..401224fe 100644 --- a/i18n/locales/vi-VN.json +++ b/i18n/locales/vi-VN.json @@ -889,5 +889,71 @@ "You do not have permission to access this page. This may be due to insufficient permissions or not being logged in.": "Bạn không có quyền truy cập trang này. Nguyên nhân có thể do quyền hạn không đủ hoặc chưa đăng nhập.", "Back to Home": "Quay lại trang chủ", "Your session has expired. Please log in again.": "Phiên làm việc của bạn đã hết hạn. Vui lòng đăng nhập lại.", - "OIDC Settings": "Cài đặt OIDC" + "OIDC Settings": "Cài đặt OIDC", + "Advanced Actions": "Thao tác nâng cao", + "Choose the backend used by SSE/KMS.": "Chọn backend dùng cho SSE/KMS.", + "Clearing cache...": "Đang xóa bộ nhớ đệm...", + "Configure the KMS backend, cache policy, and default SSE key.": "Cấu hình backend KMS, chính sách bộ nhớ đệm và khóa SSE mặc định.", + "Create a new KMS key and optionally make it the default SSE key.": "Tạo khóa KMS mới và tùy chọn đặt làm khóa SSE mặc định.", + "Default SSE Key": "Khóa SSE mặc định", + "Default SSE key updated successfully": "Đã cập nhật khóa SSE mặc định", + "Delete Immediately": "Xóa ngay", + "Delete Key Immediately": "Xóa khóa ngay", + "Describe the purpose of this key": "Mô tả mục đích của khóa này", + "Enable KMS Cache": "Bật bộ nhớ đệm KMS", + "Enter an absolute path such as D:/data/kms-keys": "Nhập đường dẫn tuyệt đối, ví dụ D:/data/kms-keys", + "Enter the default SSE key ID": "Nhập ID khóa SSE mặc định", + "Failed to cancel key deletion": "Không thể hủy xóa khóa", + "Failed to create KMS key": "Không thể tạo khóa KMS", + "Failed to force delete key": "Không thể xóa khóa ngay", + "Failed to restart KMS service": "Không thể khởi động lại dịch vụ KMS", + "Failed to save KMS configuration": "Không thể lưu cấu hình KMS", + "Failed to schedule key deletion": "Không thể lên lịch xóa khóa", + "Failed to update key status": "Không thể cập nhật trạng thái khóa", + "KMS Backend": "Backend KMS", + "KMS Key Details": "Chi tiết khóa KMS", + "KMS configuration saved successfully": "Đã lưu cấu hình KMS", + "KMS configuration updated successfully": "Đã cập nhật cấu hình KMS", + "KMS configured but not started": "Đã cấu hình KMS nhưng chưa khởi động", + "KMS key created successfully": "Đã tạo khóa KMS", + "KMS service restarted successfully": "Đã khởi động lại dịch vụ KMS", + "KV Mount": "Gắn KV", + "Key Path Prefix": "Tiền tố đường dẫn khóa", + "Key created but could not update the default SSE key. Save the configuration form and try again.": "Đã tạo khóa nhưng không thể cập nhật khóa SSE mặc định. Lưu biểu mẫu cấu hình rồi thử lại.", + "Key deleted immediately": "Đã xóa khóa ngay", + "Key deletion canceled successfully": "Đã hủy xóa khóa", + "Key deletion scheduled successfully": "Đã lên lịch xóa khóa", + "Keys in PendingDeletion can still be restored or deleted immediately.": "Khóa ở trạng thái PendingDeletion vẫn có thể khôi phục hoặc xóa ngay.", + "Local Key Directory": "Thư mục khóa cục bộ", + "Local filesystem": "Hệ thống tệp cục bộ", + "No key details available": "Không có chi tiết khóa", + "Not set": "Chưa đặt", + "Optional Vault namespace": "Namespace Vault tùy chọn", + "Optional display name for the key": "Tên hiển thị tùy chọn cho khóa", + "Please enter Vault transit mount path": "Nhập đường dẫn mount transit Vault", + "Please enter an absolute local key directory path": "Nhập đường dẫn tuyệt đối tới thư mục khóa cục bộ", + "Reconfigure KMS": "Cấu hình lại KMS", + "Reset to Current Status": "Đặt lại theo trạng thái hiện tại", + "Restart KMS": "Khởi động lại KMS", + "Restore Key": "Khôi phục khóa", + "Schedule Deletion": "Lên lịch xóa", + "Schedule Key Deletion": "Lên lịch xóa khóa", + "Set as default SSE key": "Đặt làm khóa SSE mặc định", + "Showing up to {count} keys per page": "Hiển thị tối đa {count} khóa mỗi trang", + "Skip TLS verification": "Bỏ qua xác minh TLS", + "Start KMS to make SSE and key management available.": "Khởi động KMS để dùng SSE và quản lý khóa.", + "Stopping KMS...": "Đang dừng KMS...", + "The directory must be an absolute path on the server.": "Thư mục phải là đường dẫn tuyệt đối trên máy chủ.", + "This key is used as the platform default for SSE-KMS.": "Khóa này là mặc định nền tảng cho SSE-KMS.", + "This permanently deletes the key immediately and cannot be undone.": "Xóa khóa vĩnh viễn ngay lập tức và không thể hoàn tác.", + "This restores the key from the pending deletion state.": "Khôi phục khóa khỏi trạng thái chờ xóa.", + "This schedules the key for deletion using the default pending window.": "Lên lịch xóa khóa với cửa sổ chờ mặc định.", + "This will update the current KMS configuration after key creation.": "Cập nhật cấu hình KMS hiện tại sau khi tạo khóa.", + "Timeout (seconds)": "Hết thời gian (giây)", + "Two-stage key deletion": "Xóa khóa hai giai đoạn", + "Use decimal values such as 384 for 0o600.": "Dùng giá trị thập phân, ví dụ 384 cho 0o600.", + "Vault AppRole is not supported in the first version of this console.": "Phiên bản đầu của console này không hỗ trợ Vault AppRole.", + "Vault Namespace": "Namespace Vault", + "Vault token authentication only": "Chỉ xác thực bằng token Vault", + "View Details": "Xem chi tiết" } diff --git a/i18n/locales/zh-CN.json b/i18n/locales/zh-CN.json index 7c4b16ba..8b025b01 100644 --- a/i18n/locales/zh-CN.json +++ b/i18n/locales/zh-CN.json @@ -963,5 +963,71 @@ "Completing SSO login...": "正在完成 SSO 登录...", "SSO Login Failed": "SSO 登录失败", "SSO Login Success": "SSO 登录成功", - "SSO login failed: invalid callback": "SSO 登录失败:无效的回调参数" + "SSO login failed: invalid callback": "SSO 登录失败:无效的回调参数", + "Advanced Actions": "高级操作", + "Choose the backend used by SSE/KMS.": "选择用于 SSE/KMS 的后端类型。", + "Clearing cache...": "正在清理缓存...", + "Configure the KMS backend, cache policy, and default SSE key.": "配置 KMS 后端、缓存策略以及默认 SSE 密钥。", + "Create a new KMS key and optionally make it the default SSE key.": "创建新的 KMS 密钥,并可选设为默认 SSE 密钥。", + "Default SSE Key": "默认 SSE 密钥", + "Default SSE key updated successfully": "默认 SSE 密钥更新成功", + "Delete Immediately": "立即删除", + "Delete Key Immediately": "立即删除密钥", + "Describe the purpose of this key": "描述该密钥的用途", + "Enable KMS Cache": "启用 KMS 缓存", + "Enter an absolute path such as D:/data/kms-keys": "输入绝对路径,例如 D:/data/kms-keys", + "Enter the default SSE key ID": "输入默认 SSE 密钥 ID", + "Failed to cancel key deletion": "取消密钥删除失败", + "Failed to create KMS key": "创建 KMS 密钥失败", + "Failed to force delete key": "立即删除密钥失败", + "Failed to restart KMS service": "重启 KMS 服务失败", + "Failed to save KMS configuration": "保存 KMS 配置失败", + "Failed to schedule key deletion": "计划删除密钥失败", + "Failed to update key status": "更新密钥状态失败", + "KMS Backend": "KMS 后端", + "KMS Key Details": "KMS 密钥详情", + "KMS configuration saved successfully": "KMS 配置保存成功", + "KMS configuration updated successfully": "KMS 配置更新成功", + "KMS configured but not started": "KMS 已配置但尚未启动", + "KMS key created successfully": "KMS 密钥创建成功", + "KMS service restarted successfully": "KMS 服务重启成功", + "KV Mount": "KV 挂载点", + "Key Path Prefix": "密钥路径前缀", + "Key created but could not update the default SSE key. Save the configuration form and try again.": "密钥已创建,但无法更新默认 SSE 密钥。请保存配置表单后重试。", + "Key deleted immediately": "密钥已立即删除", + "Key deletion canceled successfully": "已成功取消密钥删除", + "Key deletion scheduled successfully": "已成功计划删除密钥", + "Keys in PendingDeletion can still be restored or deleted immediately.": "处于 PendingDeletion 状态的密钥仍可恢复或立即删除。", + "Local Key Directory": "本地密钥目录", + "Local filesystem": "本地文件系统", + "No key details available": "暂无密钥详情", + "Not set": "未设置", + "Optional Vault namespace": "可选的 Vault namespace", + "Optional display name for the key": "密钥的可选显示名称", + "Please enter Vault transit mount path": "请输入 Vault transit 挂载路径", + "Please enter an absolute local key directory path": "请输入本地密钥目录的绝对路径", + "Reconfigure KMS": "重新配置 KMS", + "Reset to Current Status": "重置为当前状态", + "Restart KMS": "重启 KMS", + "Restore Key": "恢复密钥", + "Schedule Deletion": "计划删除", + "Schedule Key Deletion": "计划删除密钥", + "Set as default SSE key": "设为默认 SSE 密钥", + "Showing up to {count} keys per page": "每页最多显示 {count} 个密钥", + "Skip TLS verification": "跳过 TLS 校验", + "Start KMS to make SSE and key management available.": "启动 KMS 后才可使用 SSE 与密钥管理功能。", + "Stopping KMS...": "正在停止 KMS...", + "The directory must be an absolute path on the server.": "该目录必须是服务端的绝对路径。", + "This key is used as the platform default for SSE-KMS.": "该密钥将作为平台默认的 SSE-KMS 密钥。", + "This permanently deletes the key immediately and cannot be undone.": "这会立即永久删除该密钥,且无法撤销。", + "This restores the key from the pending deletion state.": "这会把密钥从待删除状态恢复。", + "This schedules the key for deletion using the default pending window.": "这会按默认等待窗口将密钥标记为计划删除。", + "This will update the current KMS configuration after key creation.": "创建密钥后会同步更新当前 KMS 配置。", + "Timeout (seconds)": "超时时间(秒)", + "Two-stage key deletion": "两段式密钥删除", + "Use decimal values such as 384 for 0o600.": "请使用十进制值,例如 384 表示 0o600。", + "Vault AppRole is not supported in the first version of this console.": "当前控制台首版不支持 Vault AppRole。", + "Vault Namespace": "Vault Namespace", + "Vault token authentication only": "仅支持 Vault Token 鉴权", + "View Details": "查看详情" } diff --git a/lib/config.ts b/lib/config.ts index f51a21e5..6d6af0ef 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -67,17 +67,17 @@ export const configManager = { configPromise = (async () => { let config: SiteConfig - const storedResult = getStoredHostConfig() - if (storedResult.config) { - config = storedResult.config + const runtimeConfig = this.loadRuntimeConfig() + if (runtimeConfig) { + config = runtimeConfig } else { - const browserResult = getCurrentBrowserConfig() - if (browserResult.config) { - config = browserResult.config + const storedResult = getStoredHostConfig() + if (storedResult.config) { + config = storedResult.config } else { - const runtimeConfig = this.loadRuntimeConfig() - if (runtimeConfig) { - config = runtimeConfig + const browserResult = getCurrentBrowserConfig() + if (browserResult.config) { + config = browserResult.config } else { const defaultResult = getServerDefaultConfig() config = defaultResult.config! diff --git a/lib/routes.ts b/lib/routes.ts index 8136b1dc..6a89d217 100644 --- a/lib/routes.ts +++ b/lib/routes.ts @@ -1,6 +1,7 @@ import { joinURL } from "ufo" -const BASE_PATH = process.env.NEXT_PUBLIC_BASE_PATH ?? "/rustfs/console" +const defaultBasePath = process.env.NODE_ENV === "development" ? "" : "/rustfs/console" +const BASE_PATH = process.env.NEXT_PUBLIC_BASE_PATH ?? defaultBasePath function getBaseURL(): string { if (typeof window !== "undefined") { diff --git a/next.config.ts b/next.config.ts index ee6d9795..6f47a334 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,8 +1,10 @@ import type { NextConfig } from "next" +const defaultBasePath = process.env.NODE_ENV === "development" ? "" : "/rustfs/console" + const nextConfig: NextConfig = { output: "export", - basePath: process.env.NEXT_PUBLIC_BASE_PATH ?? "/rustfs/console", + basePath: process.env.NEXT_PUBLIC_BASE_PATH ?? defaultBasePath, trailingSlash: true, images: { unoptimized: true, diff --git a/types/kms.ts b/types/kms.ts new file mode 100644 index 00000000..c6a8e2ef --- /dev/null +++ b/types/kms.ts @@ -0,0 +1,145 @@ +export type KmsServiceStatus = "NotConfigured" | "Configured" | "Running" | { Error: string } + +export type KmsBackendType = "Local" | "Vault" + +export interface KmsCacheSummary { + enabled?: boolean + max_cached_keys?: number | null + cache_ttl_seconds?: number | null + ttl_seconds?: number | null +} + +export interface KmsBackendSummary { + key_dir?: string | null + file_permissions?: number | null + address?: string | null + namespace?: string | null + mount_path?: string | null + kv_mount?: string | null + key_path_prefix?: string | null + skip_tls_verify?: boolean | null + timeout_seconds?: number | null + retry_attempts?: number | null +} + +export interface KmsConfigSummary { + default_key_id?: string | null + enable_cache?: boolean | null + max_cached_keys?: number | null + cache_ttl_seconds?: number | null + cache_summary?: KmsCacheSummary | null + backend_summary?: KmsBackendSummary | null +} + +export interface KmsServiceStatusResponse { + status: KmsServiceStatus + backend_type: KmsBackendType | null + healthy: boolean | null + config_summary: KmsConfigSummary | null +} + +export interface KmsMutationResponse { + success?: boolean + message?: string + status?: string +} + +export interface KmsStartRequest { + force?: boolean +} + +export interface KmsLocalConfigPayload { + backend_type: "local" + key_dir: string + file_permissions?: number + default_key_id?: string + timeout_seconds?: number + retry_attempts?: number + enable_cache?: boolean + max_cached_keys?: number + cache_ttl_seconds?: number +} + +export interface KmsVaultTokenAuthMethod { + Token: { + token: string + } +} + +export interface KmsVaultConfigPayload { + backend_type: "vault" + address: string + auth_method: KmsVaultTokenAuthMethod + namespace?: string | null + mount_path: string + kv_mount?: string | null + key_path_prefix?: string | null + skip_tls_verify?: boolean + default_key_id?: string + timeout_seconds?: number + retry_attempts?: number + enable_cache?: boolean + max_cached_keys?: number + cache_ttl_seconds?: number +} + +export type KmsConfigPayload = KmsLocalConfigPayload | KmsVaultConfigPayload + +export interface KmsKeyInfo { + key_id: string + description?: string | null + algorithm?: string | null + usage?: string | null + status?: string | null + version?: number | null + metadata?: Record | null + tags?: Record | null + created_at?: string | null + rotated_at?: string | null + created_by?: string | null +} + +export interface KmsKeyListResponse extends KmsMutationResponse { + keys?: KmsKeyInfo[] + truncated?: boolean + next_marker?: string | null +} + +export interface KmsCreateKeyRequest { + key_usage?: string + description?: string + tags?: Record +} + +export interface KmsCreateKeyResponse extends KmsMutationResponse { + key_id?: string + key_metadata?: KmsKeyMetadata | null +} + +export interface KmsKeyMetadata { + key_id: string + key_state?: "Enabled" | "Disabled" | "PendingDeletion" | "PendingImport" | "Unavailable" | string + key_usage?: string | null + description?: string | null + creation_date?: string | null + deletion_date?: string | null + origin?: string | null + key_manager?: string | null + tags?: Record | null + metadata?: Record | null + algorithm?: string | null + version?: number | null +} + +export interface KmsKeyDetailResponse extends KmsMutationResponse { + key_metadata?: KmsKeyMetadata | null +} + +export interface KmsDeleteKeyOptions { + pending_window_in_days?: number + force_immediate?: boolean +} + +export interface KmsCancelDeletionRequest { + key_id: string +}