Files
Charon/frontend/src/locales/en/translation.json
GitHub Actions 2b2d907b0c fix: enhance notifications and validation features
- Added URL validation for notification providers to ensure only valid http/https URLs are accepted.
- Implemented tests for URL validation scenarios in the Notifications component.
- Updated translations for error messages related to invalid URLs in multiple languages.
- Introduced new hooks for managing security headers and access lists in tests.
- Enhanced the ProviderForm component to reset state correctly when switching between add and edit modes.
- Improved user feedback with update indicators after saving changes to notification providers.
- Added mock implementations for new hooks in various test files to ensure consistent testing behavior.
2026-02-10 22:01:45 +00:00

1337 lines
59 KiB
JSON

{
"accessibility": {
"skipToContent": "Skip to main content"
},
"common": {
"save": "Save",
"cancel": "Cancel",
"delete": "Delete",
"edit": "Edit",
"add": "Add",
"create": "Create",
"update": "Update",
"close": "Close",
"copy": "Copy",
"copied": "Copied",
"confirm": "Confirm",
"back": "Back",
"next": "Next",
"loading": "Loading...",
"error": "Error",
"success": "Success",
"warning": "Warning",
"info": "Info",
"yes": "Yes",
"no": "No",
"enabled": "Enabled",
"disabled": "Disabled",
"name": "Name",
"description": "Description",
"actions": "Actions",
"status": "Status",
"search": "Search",
"filter": "Filter",
"settings": "Settings",
"language": "Language",
"configure": "Configure",
"test": "Test",
"docs": "Docs",
"upload": "Upload",
"active": "Active",
"type": "Type",
"rules": "Rules",
"allow": "Allow",
"deny": "Deny",
"saveConfiguration": "Save Configuration",
"enabledCount": "{{count}} enabled",
"validCount": "{{count}} valid",
"activeCount": "{{count}} active",
"noHistoryAvailable": "No history available",
"autoRefreshing": "Auto-refreshing every {{seconds}}s",
"score": "Score"
},
"navigation": {
"dashboard": "Dashboard",
"proxyHosts": "Proxy Hosts",
"remoteServers": "Remote Servers",
"domains": "Domains",
"certificates": "Certificates",
"dns": "DNS",
"dnsProviders": "DNS Providers",
"security": "Security",
"accessLists": "Access Lists",
"crowdsec": "CrowdSec",
"rateLimiting": "Rate Limiting",
"waf": "WAF",
"uptime": "Uptime",
"notifications": "Notifications",
"users": "Users",
"tasks": "Tasks",
"settings": "Settings",
"system": "System",
"email": "Email (SMTP)",
"adminAccount": "Admin Account",
"accountManagement": "Account Management",
"import": "Import",
"caddyfile": "Caddyfile",
"importNPM": "Import NPM",
"importJSON": "Import JSON",
"backups": "Backups",
"logs": "Logs",
"securityHeaders": "Security Headers",
"expandSidebar": "Expand sidebar",
"collapseSidebar": "Collapse sidebar",
"encryption": "Encryption",
"admin": "Admin",
"plugins": "Plugins"
},
"dashboard": {
"title": "Dashboard",
"description": "Overview of your Charon reverse proxy",
"proxyHosts": "Proxy Hosts",
"remoteServers": "Remote Servers",
"certificates": "Certificates",
"accessLists": "Access Lists",
"systemStatus": "System Status",
"healthy": "Healthy",
"unhealthy": "Unhealthy",
"pendingCertificates": "Pending certificates",
"allCertificatesValid": "All certificates valid",
"activeHosts": "{{count}} active",
"activeServers": "{{count}} active",
"activeLists": "{{count}} active",
"validCerts": "{{count}} valid"
},
"settings": {
"title": "Settings",
"description": "Configure your Charon instance",
"system": "System",
"smtp": "Email (SMTP)",
"account": "Account",
"language": "Language",
"languageDescription": "Select your preferred language",
"theme": "Theme",
"themeDescription": "Choose light or dark theme"
},
"proxyHosts": {
"title": "Proxy Hosts",
"description": "Manage your reverse proxy configurations",
"addHost": "Add Proxy Host",
"editHost": "Edit Proxy Host",
"deleteHost": "Delete Proxy Host",
"domainNames": "Domain Names",
"forwardHost": "Forward Host",
"forwardPort": "Forward Port",
"sslEnabled": "SSL Enabled",
"sslForced": "Force SSL",
"columnName": "Name",
"columnDomain": "Domain",
"columnForwardTo": "Forward To",
"columnSSL": "SSL",
"columnFeatures": "Features",
"columnStatus": "Status",
"columnActions": "Actions",
"unnamed": "Unnamed",
"staging": "Staging",
"websocket": "WS",
"acl": "ACL",
"noHosts": "No proxy hosts",
"noHostsDescription": "Create your first proxy host to get started routing traffic to your services.",
"selectedCount": "{{count}} host(s) selected",
"selectedCountAll": "(all)",
"bulkApply": "Bulk Apply",
"manageACL": "Manage ACL",
"deleteConfirmTitle": "Delete Proxy Host?",
"deleteConfirmMessage": "Are you sure you want to delete <strong>{{name}}</strong>? This action cannot be undone.",
"bulkApplyTitle": "Bulk Apply Settings",
"bulkApplyDescription": "Applying settings to <strong>{{count}}</strong> selected host(s)",
"applyACLTitle": "Apply Access List",
"applyACLDescription": "Applying to <strong>{{count}}</strong> selected host(s). Each proxy host can have a single Access Control List applied.",
"applyACL": "Apply ACL",
"removeACL": "Remove ACL",
"selectedACLCount": "{{selected}} of {{total}} selected",
"selectAll": "Select All",
"clear": "Clear",
"noEnabledACLs": "No enabled access lists available",
"removeACLWarning": "This will remove the access list from all {{count}} selected host(s).",
"publicAccessWarning": "The hosts will become publicly accessible.",
"applyingACLs": "Applying ACLs... ({{current}}/{{total}})",
"bulkDeleteTitle": "Delete {{count}} Proxy Host(s)?",
"bulkDeleteDescription": "This action cannot be undone. A backup will be created automatically before deletion.",
"hostsToDelete": "Hosts to be deleted:",
"backupInfo": "An automatic backup will be created before deletion. You can restore from the Backups page if needed.",
"creatingBackup": "Creating Backup...",
"deletePermanently": "Delete Permanently",
"ferryingNewHost": "Ferrying new host...",
"ferryingNewHostSub": "Charon is crossing the Styx",
"guidingChanges": "Guiding changes across...",
"guidingChangesSub": "Configuration in transit",
"returningToShore": "Returning to shore...",
"returningToShoreSub": "Host departure in progress",
"ferryingSouls": "Ferrying {{count}} souls...",
"ferryingSoulsSub": "Bulk operation crossing the river",
"ferryingConfig": "Ferrying configuration...",
"sslForce": "Force SSL",
"http2Support": "HTTP/2 Support",
"hstsEnabled": "HSTS Enabled",
"hstsSubdomains": "HSTS Subdomains",
"blockExploits": "Block Exploits",
"websocketSupport": "WebSocket Support",
"apply": "Apply",
"applyCount": "Apply ({{count}})",
"bulkApplySecurityHeaders": "Security Header Profile",
"bulkApplySecurityHeadersHelp": "Apply a security header profile to all selected hosts",
"noSecurityProfile": "None (Remove Profile)",
"removeSecurityHeadersWarning": "This will remove the security header profile from all selected hosts, potentially reducing their security posture."
},
"certificates": {
"title": "SSL Certificates",
"description": "Manage SSL/TLS certificates for your proxy hosts",
"addCertificate": "Add Certificate",
"uploadCertificate": "Upload Certificate",
"domain": "Domain",
"status": "Status",
"expiresAt": "Expires At",
"valid": "Valid",
"pending": "Pending",
"expired": "Expired",
"friendlyName": "Friendly Name",
"certificatePem": "Certificate (PEM)",
"privateKeyPem": "Private Key (PEM)",
"uploadSuccess": "Certificate uploaded successfully",
"uploadFailed": "Failed to upload certificate",
"note": "Note",
"noteText": "You can delete custom certificates and staging certificates. Production Let's Encrypt certificates are automatically renewed and should not be deleted unless switching environments."
},
"auth": {
"login": "Login",
"logout": "Logout",
"email": "Email",
"password": "Password",
"username": "Username",
"signIn": "Sign In",
"signOut": "Sign Out",
"forgotPassword": "Forgot Password?",
"rememberMe": "Remember Me",
"checkingSetup": "Checking setup status...",
"loggingIn": "Paying the ferryman...",
"loggingInSub": "Your obol grants passage",
"loginSuccess": "Logged in successfully",
"loginFailed": "Login failed",
"resetPasswordTitle": "To reset your password:",
"resetPasswordInstructions": "Run this command on your server:"
},
"errors": {
"required": "This field is required",
"invalidEmail": "Invalid email address",
"passwordTooShort": "Password must be at least 8 characters",
"genericError": "An error occurred. Please try again.",
"networkError": "Network error. Please check your connection.",
"unauthorized": "Unauthorized. Please login again.",
"notFound": "Resource not found",
"serverError": "Server error. Please try again later."
},
"notifications": {
"saveSuccess": "Changes saved successfully",
"deleteSuccess": "Deleted successfully",
"createSuccess": "Created successfully",
"updateSuccess": "Updated successfully",
"saveFailed": "Failed to save changes",
"deleteFailed": "Failed to delete",
"createFailed": "Failed to create",
"updateFailed": "Failed to update",
"partialFailed": "Completed with {{count}} error(s)"
},
"security": {
"title": "Security",
"description": "Configure security layers for your reverse proxy",
"cerberusDashboard": "Cerberus Dashboard",
"cerberusActive": "Active",
"cerberusDisabled": "Disabled",
"cerberusReadyMessage": "All security heads are ready for configuration",
"cerberusDisabledMessage": "Enable Cerberus in System Settings to activate security features",
"featuresUnavailable": "Security Features Unavailable",
"featuresUnavailableMessage": "Cerberus powers CrowdSec, Coraza WAF, Access Control, and Rate Limiting. Enable the Cerberus toggle in System Settings to activate these features.",
"learnMore": "Learn More",
"adminWhitelist": "Admin Whitelist",
"adminWhitelistDescription": "Configure IP addresses that bypass security checks",
"commaSeparatedCIDR": "Comma-separated CIDR/IPs",
"generateToken": "Generate Token",
"generateTokenTooltip": "Generate a break-glass token for emergency access",
"enableCerberusFirst": "Enable Cerberus first",
"layer": "Layer",
"auditLogs": "Audit Logs",
"crowdsec": {
"title": "CrowdSec",
"subtitle": "IP Reputation & Threat Intelligence",
"badge": "IDS",
"enabledDescription": "Protects against: Known attackers, botnets, brute-force",
"disabledDescription": "Intrusion Prevention System powered by community threat intelligence",
"processRunning": "Running (PID {{pid}})",
"processStopped": "Process stopped",
"toggleTooltip": "Toggle CrowdSec protection",
"bouncerApiKey": "Bouncer API Key",
"keyCopied": "API key copied to clipboard",
"copyFailed": "Failed to copy API key",
"noKeyConfigured": "No bouncer key configured. Enable CrowdSec to auto-register.",
"registered": "Registered",
"notRegistered": "Not Registered",
"sourceEnvVar": "From environment variable",
"sourceFile": "From file",
"keyStoredAt": "Key stored at",
"keyWarning": {
"title": "CrowdSec API Key Updated",
"description": "Your configured API key was rejected by CrowdSec LAPI. A new key has been automatically generated to restore protection.",
"instructions": "Update your docker-compose.yml with the new key to prevent re-registration on container restart:",
"copyButton": "Copy",
"copied": "Key copied to clipboard",
"restartNote": "After updating docker-compose.yml, restart the container for the change to take effect."
}
},
"acl": {
"title": "Access Control",
"subtitle": "IP & Geo-based filtering",
"badge": "ACL",
"description": "Protects against: Unauthorized IPs, geo-based attacks, insider threats",
"manageLists": "Manage Lists",
"toggleTooltip": "Toggle Access Control"
},
"waf": {
"title": "Coraza WAF",
"subtitle": "Request inspection & filtering",
"badge": "WAF",
"enabledDescription": "Protects against: SQL injection, XSS, RCE, zero-day exploits*",
"disabledDescription": "Web Application Firewall with OWASP Core Rule Set",
"toggleTooltip": "Toggle Coraza WAF"
},
"rateLimit": {
"title": "Rate Limiting",
"subtitle": "Request volume control",
"badge": "Rate",
"description": "Protects against: DDoS attacks, credential stuffing, API abuse",
"toggleTooltip": "Toggle Rate Limiting"
},
"notifications": "Notifications",
"threeHeadsTurn": "Three heads turn...",
"cerberusConfigUpdating": "Cerberus configuration updating",
"summoningGuardian": "Summoning the guardian...",
"crowdsecStarting": "CrowdSec is starting",
"guardianRests": "Guardian rests...",
"crowdsecStopping": "CrowdSec is stopping",
"strengtheningGuard": "Strengthening the guard...",
"wardsActivating": "Protective wards activating",
"layer1": "Layer 1",
"layer2": "Layer 2",
"layer3": "Layer 3",
"layer4": "Layer 4",
"ids": "IDS",
"acl": "ACL",
"waf": "WAF",
"rate": "Rate",
"crowdsec": "CrowdSec",
"crowdsecDescription": "IP Reputation & Threat Intelligence",
"crowdsecProtects": "Protects against: Known attackers, botnets, brute-force",
"crowdsecDisabledDescription": "Intrusion Prevention System powered by community threat intelligence",
"runningPid": "Running (PID {{pid}})",
"processStopped": "Process stopped",
"toggleCrowdsec": "Toggle CrowdSec protection",
"accessControl": "Access Control",
"aclDescription": "IP & Geo-based filtering",
"aclProtects": "Protects against: Unauthorized IPs, geo-based attacks, insider threats",
"toggleAcl": "Toggle Access Control",
"manageLists": "Manage Lists",
"corazaWaf": "Coraza WAF",
"wafDescription": "Request inspection & filtering",
"wafProtects": "Protects against: SQL injection, XSS, RCE, zero-day exploits*",
"wafDisabledDescription": "Web Application Firewall with OWASP Core Rule Set",
"toggleWaf": "Toggle Coraza WAF",
"rateLimiting": "Rate Limiting",
"rateLimitDescription": "Request volume control",
"rateLimitProtects": "Protects against: DDoS attacks, credential stuffing, API abuse",
"toggleRateLimit": "Toggle Rate Limiting",
"failedToLoadConfiguration": "Failed to load security configuration"
},
"accessLists": {
"title": "Access Lists",
"description": "Manage IP-based access control",
"createAccessList": "Create Access List",
"editAccessList": "Edit Access List",
"deleteAccessList": "Delete Access List",
"deleteSelected": "Delete ({{count}})",
"bestPractices": "Best Practices",
"testIP": "Test IP",
"testIPAddress": "Test IP Address",
"ipAddress": "IP Address",
"accessList": "Access List",
"rfc1918Only": "RFC1918 Only",
"cgnatWarning": {
"title": "CGNAT & Mobile Network Warning",
"message": "If you're using T-Mobile 5G Home Internet, Starlink, or other CGNAT connections, geo-blocking may not work as expected. Your IP may appear to be from a data center location, not your physical location.",
"solutionsTitle": "Solutions if you're locked out:",
"solution1": "Access via local network IP (192.168.x.x) - ACLs don't apply to local IPs",
"solution2": "Add your current IP to a whitelist ACL",
"solution3": "Use \"Test IP\" below to check what IP the server sees",
"solution4": "Disable the ACL temporarily to regain access",
"solution5": "Connect via VPN with a known good IP address"
},
"deleteConfirmTitle": "Delete Access List",
"deleteConfirmMessage": "Are you sure you want to delete \"{{name}}\"? A backup will be created before deletion.",
"bulkDeleteConfirmTitle": "Delete Selected Access Lists",
"bulkDeleteConfirmMessage": "Are you sure you want to delete {{count}} access list(s)? A backup will be created before deletion.",
"deleteItems": "Delete {{count}} Items",
"deleting": "Deleting...",
"noAccessLists": "No Access Lists",
"noAccessListsDescription": "Create your first access list to control who can access your services"
},
"rateLimiting": {
"title": "Rate Limiting Configuration",
"description": "Control request rates to protect your services from abuse",
"aboutTitle": "About Rate Limiting",
"aboutDescription": "Rate limiting helps protect your services from abuse, brute-force attacks, and excessive resource consumption. Configure limits per client IP address.",
"currentlyActive": "Currently Active",
"currentConfig": "{{requests}} requests/sec • Burst: {{burst}} • Window: {{window}}s",
"enableRateLimiting": "Enable Rate Limiting",
"enabledMessage": "Rate limiting is active and protecting your services",
"disabledMessage": "Enable to start limiting request rates",
"configuration": "Configuration",
"requestsPerSecond": "Requests per Second",
"requestsPerSecondHelper": "Maximum requests allowed per second per client",
"burst": "Burst",
"burstHelper": "Allow short bursts above the rate limit",
"windowSeconds": "Window (seconds)",
"windowHelper": "Time window for rate calculations",
"rateLimitingDisabled": "Rate Limiting Disabled",
"enableToConfigureMessage": "Enable rate limiting to configure request limits and protect your services",
"adjustingGates": "Adjusting the gates...",
"configurationUpdating": "Rate limiting configuration updating"
},
"wafConfig": {
"title": "WAF Configuration",
"description": "Manage Coraza Web Application Firewall rule sets",
"addRuleSet": "Add Rule Set",
"createRuleSet": "Create Rule Set",
"editRuleSet": "Edit Rule Set",
"updateRuleSet": "Update Rule Set",
"deleteRuleSet": "Delete Rule Set",
"ruleSyntax": "Rule Syntax",
"aboutTitle": "About WAF Rule Sets",
"aboutDescription": "Rule sets define ModSecurity/Coraza rules that inspect and filter HTTP requests. The WAF automatically enables SecRuleEngine On and SecRequestBodyAccess On for your rules.",
"deleteConfirmTitle": "Delete Rule Set",
"deleteConfirmMessage": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.",
"noRuleSets": "No Rule Sets",
"noRuleSetsDescription": "Create your first WAF rule set to protect your services from web attacks",
"ruleSetName": "Rule Set Name",
"mode": "Mode",
"blocking": "Blocking",
"detection": "Detection",
"detectionOnly": "Detection Only",
"blockingDescription": "Malicious requests will be blocked with HTTP 403",
"detectionDescription": "Malicious requests will be logged but not blocked",
"sourceUrl": "Source URL (optional)",
"sourceUrlHelper": "URL to fetch rules from. Leave empty to use inline content.",
"ruleContent": "Rule Content",
"ruleContentHelper": "ModSecurity/Coraza rule syntax. Each SecRule should be on its own line.",
"source": "Source",
"url": "URL",
"inline": "Inline",
"lastUpdated": "Last Updated",
"rulesCount": "{{count}} rule(s)",
"quickStartPreset": "Quick Start with Preset",
"choosePreset": "Choose a preset...",
"cerberusAwakens": "Cerberus awakens...",
"guardianWatches": "Guardian of the gates stands watch",
"forgingDefenses": "Forging new defenses...",
"rulesInscribing": "Security rules inscribing",
"loweringBarrier": "Lowering a barrier...",
"defenseRemoved": "Defense layer removed",
"loadingWaf": "Loading WAF configuration...",
"loadingFailed": "Failed to load WAF configuration",
"loadingConfiguration": "Loading WAF configuration...",
"failedToLoad": "Failed to load WAF configuration",
"deleteConfirmation": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.",
"ruleCount": "{{count}} rule(s)"
},
"uptime": {
"title": "Uptime Monitoring",
"description": "Monitor the health and availability of your services",
"autoRefresh": "Auto-refreshing every 30s",
"autoRefreshing": "Auto-refreshing every 30s",
"noMonitors": "No monitors found. Add a Proxy Host or Remote Server to start monitoring.",
"noMonitorsFound": "No monitors found. Add a Proxy Host or Remote Server to start monitoring.",
"proxyHosts": "Proxy Hosts",
"remoteServers": "Remote Servers",
"otherMonitors": "Other Monitors",
"configureMonitor": "Configure Monitor",
"monitorName": "Name",
"maxRetries": "Max Retries",
"maxRetriesHelper": "Number of consecutive failures before sending an alert.",
"checkInterval": "Check Interval (seconds)",
"saveChanges": "Save Changes",
"saving": "Saving...",
"latency": "Latency",
"lastCheck": "Last Check",
"last60Checks": "Last 60 health checks",
"never": "Never",
"paused": "PAUSED",
"unpaused": "Unpaused",
"pause": "Pause",
"unpause": "Unpause",
"triggerCheck": "Trigger immediate health check",
"triggerHealthCheck": "Trigger immediate health check",
"monitorSettings": "Monitor settings",
"healthCheckTriggered": "Health check triggered",
"monitorDeleted": "Monitor deleted",
"deleteConfirm": "Delete this monitor? This cannot be undone.",
"deleteConfirmation": "Delete this monitor? This cannot be undone.",
"loadingMonitors": "Loading monitors...",
"failedToDeleteMonitor": "Failed to delete monitor",
"failedToUpdateMonitor": "Failed to update monitor",
"failedToTriggerCheck": "Failed to trigger health check",
"noHistoryAvailable": "No history available",
"addMonitor": "Add Monitor",
"syncWithHosts": "Sync with Hosts",
"createMonitor": "Create Monitor",
"monitorCreated": "Monitor created successfully",
"syncComplete": "Sync complete",
"syncing": "Syncing...",
"monitorType": "Type",
"monitorUrl": "URL",
"monitorTypeHttp": "HTTP",
"monitorTypeTcp": "TCP",
"urlPlaceholder": "https://example.com or tcp://host:port"
},
"domains": {
"title": "Domains",
"description": "Manage your domains",
"addDomain": "Add Domain",
"deleteDomain": "Delete Domain",
"domainName": "Domain Name",
"placeholder": "example.com",
"adding": "Adding...",
"added": "Added {{date}}",
"deleteConfirm": "Are you sure you want to delete this domain?",
"createFailed": "Failed to create domain",
"deleteFailed": "Failed to delete domain",
"loadError": "Error loading domains"
},
"remoteServers": {
"title": "Remote Servers",
"description": "Manage backend servers for your proxy hosts",
"addServer": "Add Server",
"editServer": "Edit Server",
"deleteServer": "Delete Remote Server",
"noServers": "No Remote Servers",
"noServersDescription": "Add servers to quickly select backends when creating proxy hosts",
"columnName": "Name",
"columnProvider": "Provider",
"columnHost": "Host",
"columnPort": "Port",
"host": "Host",
"port": "Port",
"user": "User",
"gridView": "Grid view",
"listView": "List view",
"deleteConfirm": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.",
"deleting": "Deleting..."
},
"notificationProviders": {
"title": "Notification Providers",
"description": "Manage notification providers and templates",
"addProvider": "Add Provider",
"addNewProvider": "Add New Provider",
"providerName": "Name",
"urlWebhook": "URL / Webhook",
"urlRequired": "URL is required",
"invalidUrl": "Please enter a valid URL starting with http:// or https://",
"genericWebhook": "Generic Webhook (Shoutrrr)",
"customWebhook": "Custom Webhook (JSON)",
"shoutrrrHelp": "For Shoutrrr format, see",
"jsonPayloadTemplate": "JSON Payload Template",
"minimalTemplate": "Minimal Template",
"detailedTemplate": "Detailed Template",
"customTemplate": "Custom",
"template": "Template",
"availableVariables": "Available variables: .Title, .Message, .Status, .Name, .Latency, .Time. Supports webhook, Discord, Slack, Gotify, and generic services.",
"notificationEvents": "Notification Events",
"proxyHosts": "Proxy Hosts",
"remoteServers": "Remote Servers",
"domainsNotify": "Domains",
"certificates": "Certificates",
"uptime": "Uptime",
"preview": "Preview",
"previewError": "Preview Error",
"previewResult": "Preview Result",
"externalTemplates": "External Templates",
"manageTemplates": "Manage Templates",
"hideTemplates": "Hide",
"newTemplate": "New Template",
"createTemplate": "Create Template",
"templateType": "Template Type",
"minimal": "Minimal",
"detailed": "Detailed",
"custom": "Custom",
"configJson": "Config (JSON/template)",
"noExternalTemplates": "No external templates. Use the form above to create one.",
"deleteTemplateConfirm": "Delete template?",
"sendTest": "Send Test Notification",
"testSent": "Test notification sent!",
"testFailed": "Failed to send test",
"deleteConfirm": "Are you sure?",
"noProviders": "No notification providers configured."
},
"users": {
"title": "User Management",
"inviteUser": "Invite User",
"inviteSent": "Invitation email sent",
"inviteCreated": "User invited - copy the invite link below",
"inviteFailed": "Failed to invite user",
"inviteLinkCopied": "Invite link copied to clipboard",
"inviteSuccess": "User Invited Successfully",
"inviteEmailSent": "An invitation email has been sent to the user.",
"inviteEmailNotSent": "Email was not sent. Share the invite link manually.",
"inviteLink": "Invite Link",
"copyInviteLink": "Copy invite link",
"expires": "Expires",
"done": "Done",
"emailAddress": "Email Address",
"role": "Role",
"roleUser": "User",
"roleAdmin": "Admin",
"permissionMode": "Permission Mode",
"allowAllBlacklist": "Allow All (Blacklist)",
"denyAllWhitelist": "Deny All (Whitelist)",
"allowAllDescription": "User can access all hosts EXCEPT those selected below",
"denyAllDescription": "User can ONLY access hosts selected below",
"blockedHosts": "Blocked Hosts",
"allowedHosts": "Allowed Hosts",
"noProxyHosts": "No proxy hosts configured",
"sendInvite": "Send Invite",
"editPermissions": "Edit Permissions",
"permissionsUpdated": "Permissions updated",
"permissionsUpdateFailed": "Failed to update permissions",
"savePermissions": "Save Permissions",
"userUpdated": "User updated",
"userUpdateFailed": "Failed to update user",
"userDeleted": "User deleted",
"userDeleteFailed": "Failed to delete user",
"columnUser": "User",
"columnRole": "Role",
"columnPermissions": "Permissions",
"noName": "(No name)",
"pendingInvite": "Pending Invite",
"inviteExpired": "Invite Expired",
"whitelist": "Whitelist",
"blacklist": "Blacklist",
"deleteConfirm": "Are you sure you want to delete this user?",
"deleteUser": "Delete User",
"inviteUrlPreview": "Invite Link Preview",
"inviteUrlWarning": "Application URL is not configured. This link may not work for external users.",
"configureApplicationUrl": "Configure Application URL",
"resendInvite": "Resend Invite",
"inviteResent": "Invitation resent successfully",
"inviteCreatedNoEmail": "New invite created. Email could not be sent.",
"resendFailed": "Failed to resend invitation"
},
"dashboard": {
"title": "Dashboard",
"description": "Overview of your Charon reverse proxy",
"proxyHosts": "Proxy Hosts",
"remoteServers": "Remote Servers",
"certificates": "Certificates",
"certificateStatus": "Certificate Status",
"accessLists": "Access Lists",
"systemStatus": "System Status",
"healthy": "Healthy",
"unhealthy": "Unhealthy",
"pendingCertificates": "Pending certificates",
"allCertificatesValid": "All certificates valid",
"activeHosts": "{{count}} active",
"activeServers": "{{count}} active",
"activeLists": "{{count}} active",
"validCerts": "{{count}} valid"
},
"setup": {
"welcomeTitle": "Welcome to Charon",
"welcomeDescription": "Create your administrator account to get started.",
"nameLabel": "Name",
"namePlaceholder": "Admin User",
"emailLabel": "Email Address",
"emailPlaceholder": "admin@example.com",
"invalidEmail": "Please enter a valid email address",
"passwordLabel": "Password",
"createAdminButton": "Create Admin Account",
"setupFailed": "Setup failed"
},
"acceptInvite": {
"title": "Accept Invitation",
"invalidLink": "Invalid Link",
"invalidLinkMessage": "This invitation link is invalid or incomplete.",
"goToLogin": "Go to Login",
"validating": "Validating invitation...",
"invitationInvalid": "Invitation Invalid",
"expiredOrInvalid": "This invitation has expired or is invalid.",
"accountCreated": "Account Created!",
"accountCreatedMessage": "Your account has been set up successfully. Redirecting to login...",
"youveBeenInvited": "You've been invited!",
"completeSetup": "Complete your account setup for",
"yourName": "Your Name",
"namePlaceholder": "John Doe",
"confirmPassword": "Confirm Password",
"passwordsDoNotMatch": "Passwords do not match",
"createAccount": "Create Account",
"welcomeMessage": "Welcome, {{email}}! You can now log in.",
"acceptFailed": "Failed to accept invitation"
},
"tasks": {
"title": "Tasks",
"description": "Manage system tasks and view logs"
},
"backups": {
"title": "Backups",
"description": "Manage database backups",
"configuration": "Configuration",
"intervalDays": "Backup Interval (Days)",
"retentionDays": "Retention Period (Days)",
"saveSettings": "Save Settings",
"settingsSaved": "Backup settings saved",
"settingsFailed": "Failed to save settings: {{error}}",
"createBackup": "Create Backup",
"createSuccess": "Backup created successfully",
"createFailed": "Failed to create backup: {{error}}",
"restoreBackup": "Restore Backup",
"restore": "Restore",
"restoreSuccess": "Backup restored successfully. Please restart the container.",
"restoreFailed": "Failed to restore backup: {{error}}",
"restoreConfirmMessage": "Are you sure you want to restore this backup? Current data will be overwritten. You will need to restart the container after restoration.",
"deleteBackup": "Delete Backup",
"deleteSuccess": "Backup deleted successfully",
"deleteFailed": "Failed to delete backup: {{error}}",
"deleteConfirmMessage": "Are you sure you want to delete \"{{filename}}\"? This action cannot be undone.",
"download": "Download",
"filename": "Filename",
"size": "Size",
"createdAt": "Created At",
"auto": "Auto",
"manual": "Manual",
"noBackups": "No Backups",
"noBackupsDescription": "Create your first backup to protect your configuration"
},
"logs": {
"title": "Logs",
"description": "View system and access logs",
"logFiles": "Log Files",
"noLogFiles": "No log files found",
"noLogSelected": "No Log Selected",
"selectLogDescription": "Select a log file from the list to view its contents",
"showingEntries": "Showing {{from}} to {{to}} of {{total}} entries",
"pageOf": "Page {{current}} of {{total}}"
},
"account": {
"title": "Account Settings",
"profile": "Profile",
"profileDescription": "Update your personal information.",
"saveProfile": "Save Profile",
"profileUpdated": "Profile updated successfully",
"profileUpdateFailed": "Failed to update profile: {{error}}",
"certificateEmail": "Certificate Email",
"certificateEmailDescription": "This email is used for Let's Encrypt notifications and recovery.",
"useAccountEmail": "Use my account email ({{email}})",
"customEmail": "Custom Email",
"saveCertificateEmail": "Save Certificate Email",
"certEmailUpdated": "Certificate email updated",
"certEmailUpdateFailed": "Failed to update certificate email: {{error}}",
"changePassword": "Change Password",
"changePasswordDescription": "Update your account password for security.",
"currentPassword": "Current Password",
"newPassword": "New Password",
"confirmNewPassword": "Confirm New Password",
"updatePassword": "Update Password",
"passwordsDoNotMatch": "Passwords do not match",
"passwordUpdated": "Password updated successfully",
"passwordUpdateFailed": "Failed to update password",
"apiKey": "API Key",
"apiKeyDescription": "Use this key to authenticate with the API programmatically. Keep it secret!",
"copyToClipboard": "Copy to clipboard",
"regenerateApiKey": "Regenerate API Key",
"apiKeyCopied": "API Key copied to clipboard",
"apiKeyRegenerated": "API Key regenerated successfully",
"apiKeyRegenerateFailed": "Failed to regenerate API key: {{error}}",
"securityNotice": "Security Notice",
"securityNoticeMessage": "Never share your API key or password with anyone. If you believe your credentials have been compromised, regenerate your API key immediately.",
"confirmPassword": "Confirm Password",
"confirmPasswordDescription": "Please enter your current password to confirm these changes.",
"enterPassword": "Enter your password",
"confirmAndUpdate": "Confirm & Update",
"updateCertEmailTitle": "Update Certificate Email?",
"updateCertEmailDescription": "You are changing your account email to {{email}}. Do you want to use this new email for SSL certificates as well?",
"yesUpdateCertEmail": "Yes, update certificate email too",
"noKeepEmail": "No, keep using {{email}}"
},
"importCaddy": {
"title": "Import Caddyfile",
"enterCaddyfileContent": "Please enter Caddyfile content",
"cancelConfirm": "Are you sure you want to cancel this import?",
"noDomainsFound": "No domains found in Caddyfile",
"emptyFileWarning": "The imported file appears to be empty or contains no valid reverse_proxy directives. Please check the file content below.",
"uploadOrPaste": "Upload or Paste Caddyfile",
"description": "Import an existing Caddyfile to automatically create proxy host configurations. The system will detect conflicts and allow you to review changes before committing.",
"warningTitle": "Import warning",
"uploadCaddyfile": "Upload Caddyfile",
"orPasteContent": "or paste content",
"caddyfileContent": "Caddyfile Content",
"processing": "Processing...",
"parseAndReview": "Parse and Review",
"multiSiteImport": "Multi-site Import"
},
"importCrowdSec": {
"title": "CrowdSec Configuration Packages",
"description": "Upload a tar.gz or zip package. A backup is created before importing so you can roll back if needed. Export the current package from the Cerberus dashboard or CrowdSec config page.",
"import": "Import",
"configImported": "CrowdSec config imported",
"importFailed": "Import failed: {{error}}",
"creatingBackup": "Creating backup...",
"importing": "Importing CrowdSec..."
},
"importNPM": {
"title": "Import from NPM",
"description": "Import proxy hosts from Nginx Proxy Manager export",
"enterContent": "Please paste NPM export JSON",
"invalidJSON": "Invalid JSON format",
"upload": "Upload & Preview",
"import": "Import",
"success": "Import completed successfully",
"previewTitle": "Preview Import",
"conflict": "Conflict",
"new": "New",
"skip": "Skip",
"keep": "Keep Existing",
"replace": "Replace",
"cancelConfirm": "Are you sure you want to cancel this import?"
},
"importJSON": {
"title": "Import from JSON",
"description": "Import configuration from JSON export",
"enterContent": "Please paste JSON configuration",
"invalidJSON": "Invalid JSON format",
"upload": "Upload & Preview",
"import": "Import",
"success": "Import completed successfully",
"previewTitle": "Preview Import",
"conflict": "Conflict",
"new": "New",
"skip": "Skip",
"keep": "Keep Existing",
"replace": "Replace",
"cancelConfirm": "Are you sure you want to cancel this import?"
},
"systemSettings": {
"title": "System Settings",
"settingsSaved": "System settings saved",
"settingsFailed": "Failed to save settings: {{error}}",
"featureFlagUpdated": "Feature flag updated",
"featureFlagFailed": "Failed to update flag: {{error}}",
"updatingFeatures": "Updating features...",
"applyingChanges": "Applying configuration changes",
"pleaseWait": "Please wait",
"saveSettings": "Save Settings",
"features": {
"title": "Features",
"description": "Enable or disable optional features for your Charon instance.",
"cerberus": "Cerberus Security Suite",
"cerberusTooltip": "Advanced security features including WAF, Access Lists, Rate Limiting, and CrowdSec.",
"crowdsecConsole": "CrowdSec Console Enrollment",
"crowdsecConsoleTooltip": "Allow enrolling this node with CrowdSec Console for centralized fleet management.",
"uptimeMonitoring": "Uptime Monitoring",
"uptimeMonitoringTooltip": "Monitor the availability of your proxy hosts and remote servers."
},
"general": {
"title": "General Configuration",
"description": "Configure Caddy and UI preferences.",
"caddyAdminApi": "Caddy Admin API Endpoint",
"caddyAdminApiHelper": "URL to the Caddy admin API (usually on port 2019)",
"sslProvider": "SSL Provider",
"selectSslProvider": "Select SSL provider",
"sslAuto": "Auto (Recommended)",
"sslLetsEncryptProd": "Let's Encrypt (Prod)",
"sslLetsEncryptStaging": "Let's Encrypt (Staging)",
"sslZeroSSL": "ZeroSSL",
"sslProviderHelper": "Choose the Certificate Authority. 'Auto' uses Let's Encrypt with ZeroSSL fallback.",
"domainLinkBehavior": "Domain Link Behavior",
"selectLinkBehavior": "Select link behavior",
"sameTab": "Same Tab",
"newTab": "New Tab (Default)",
"newWindow": "New Window",
"domainLinkBehaviorHelper": "Control how domain links open in the Proxy Hosts list.",
"languageHelper": "Select your preferred language. Changes take effect immediately."
},
"applicationUrl": {
"title": "Application URL",
"description": "Configure the public URL used for user-facing links and emails.",
"label": "Application URL",
"helper": "The public URL where users access Charon (e.g., https://charon.example.com). Used in invitation emails and password reset links.",
"infoMessage": "This URL is used when sending invitation emails. If not configured, Charon will use the URL from the current browser request, which may not be accessible from external networks.",
"invalidUrl": "Please enter a valid URL starting with http:// or https://",
"notConfiguredWarning": "Application URL is not configured. Invitation emails will use the current browser URL, which may not be accessible from external networks.",
"testButton": "Test URL"
},
"systemStatus": {
"title": "System Status",
"service": "Service",
"version": "Version",
"buildTime": "Build Time",
"gitCommit": "Git Commit",
"notAvailable": "N/A",
"fetchError": "Unable to fetch system status. Please check your connection."
},
"updates": {
"title": "Software Updates",
"description": "Check for new versions of Charon.",
"currentVersion": "Current Version",
"latestVersion": "Latest Version",
"updateAvailable": "Update Available",
"newVersionAvailable": "A new version of Charon is available!",
"viewReleaseNotes": "View Release Notes",
"upToDate": "Up to Date",
"runningLatest": "You are running the latest version of Charon.",
"checkForUpdates": "Check for Updates"
}
},
"crowdsecConfig": {
"title": "CrowdSec Configuration",
"loading": "Loading CrowdSec configuration...",
"loadError": "Error loading CrowdSec status",
"noStatus": "CrowdSec status unavailable",
"noConfig": "CrowdSec configuration not found in security status",
"note": "Note",
"noteText": "CrowdSec is controlled via the toggle on the",
"consoleEnrollment": {
"title": "Console Enrollment",
"description": "Connect your CrowdSec LAPI to the CrowdSec Console for centralized management and alerts.",
"privacyNote": "Note: Enrollment sends heartbeat data and metrics to CrowdSec. See CrowdSec's privacy policy for details.",
"lastHeartbeat": "Last heartbeat",
"enrollToken": "Enrollment Token",
"tokenHelper": "Get your enrollment token from the CrowdSec Console",
"tenantHelper": "Optional: specify the tenant/organization ID if using multi-tenant setup",
"ackText": "I understand this will rotate my LAPI credentials if already enrolled",
"status": "Status",
"notEnrolled": "Not Enrolled",
"enrolled": "Enrolled",
"pending": "Pending",
"enrolling": "Enrolling...",
"pendingAcceptance": "Pending Acceptance",
"unknown": "Unknown",
"lapiNotReady": "LAPI is not yet ready. CrowdSec may still be starting.",
"checkLapiStatus": "Check LAPI Status",
"startCrowdSec": "Start CrowdSec",
"goToSecurity": "Go to Security Dashboard",
"enrollmentToken": "Enrollment Token",
"tokenPlaceholder": "Paste your enrollment token from CrowdSec Console",
"agentName": "Agent Name (optional)",
"agentPlaceholder": "my-charon-instance",
"tenant": "Tenant/Organization (optional)",
"tenantPlaceholder": "org-id-from-console",
"acknowledge": "I acknowledge this will rotate credentials if already enrolled",
"enroll": "Enroll",
"rotateKey": "Rotate Key",
"retryEnrollment": "Retry Enrollment",
"lapiMustBeReady": "LAPI must be ready to enroll",
"lapiMustBeReadyRotate": "LAPI must be ready to rotate key",
"lapiMustBeReadyRetry": "LAPI must be ready to retry enrollment",
"tokenRequired": "Enrollment token is required",
"actionRequired": "Action Required",
"pendingAcceptanceText": "Your enrollment request has been submitted. Please accept this machine in the CrowdSec Console at",
"pendingAcceptanceNote": " Once accepted, the status will update automatically.",
"agent": "Agent",
"tenantLabel": "Tenant",
"lastAttempt": "Last attempt",
"enrolledAt": "Enrolled",
"correlationId": "Correlation ID"
},
"reenroll": {
"title": "Re-enrollment Options",
"description": "Need to switch enrollment keys or move to a different organization?",
"getNewKey": "Get new enrollment key from Console",
"withNewKey": "Re-enroll with new key",
"newEnrollmentKey": "New Enrollment Key",
"keyPlaceholder": "Paste new enrollment key",
"agentPlaceholder": "Leave empty to keep current name",
"tenantOptional": "Tenant/Organization (optional)",
"orgPlaceholder": "Leave empty to keep current",
"reenroll": "Re-enroll",
"reenrolling": "Re-enrolling...",
"clearState": "Clear enrollment state",
"clearing": "Clearing...",
"clearConfirm": "This will clear local enrollment state. You may need to re-enroll. Continue?"
},
"packages": {
"title": "Configuration Packages",
"description": "Export or import CrowdSec configuration packages (tar.gz/zip). A backup is created before importing.",
"export": "Export",
"import": "Import",
"importing": "Importing..."
},
"presets": {
"title": "Presets",
"description": "Apply curated or hub configuration presets.",
"searchPlaceholder": "Search presets...",
"sortAlpha": "Sort: A-Z",
"sortSource": "Sort: Source",
"curated": "Curated",
"hub": "Hub",
"noResults": "No presets match \"{{query}}\"",
"pullPreview": "Pull Preview",
"applyPreset": "Apply Preset",
"hubUnreachable": "CrowdSec Hub unreachable. Hub presets may not work.",
"retry": "Retry",
"useCached": "Use Cached",
"targetFile": "Target file",
"selectFileBelow": "(select a config file below)",
"cacheKey": "Cache Key",
"etag": "ETag",
"source": "Source",
"fetched": "Fetched",
"previewYaml": "Preview (YAML):",
"previewUnavailable": "Preview unavailable",
"applied": "Applied",
"backup": "Backup",
"reload": "Reload",
"required": "Required",
"method": "Method",
"filesystem": "Filesystem",
"loadCached": "Load cached preview",
"applyDisabled": "Apply disabled while hub is offline.",
"noPresets": "No presets available. Ensure Cerberus is enabled."
},
"files": {
"title": "Edit Configuration Files",
"selectFile": "Select a file...",
"refresh": "Refresh"
},
"bannedIps": {
"title": "Banned IPs",
"banIp": "Ban IP",
"enableFirst": "Enable CrowdSec to manage banned IPs",
"loading": "Loading banned IPs...",
"loadFailed": "Failed to load banned IPs",
"none": "No banned IPs",
"ip": "IP",
"reason": "Reason",
"duration": "Duration",
"bannedAt": "Banned At",
"source": "Source",
"actions": "Actions",
"unban": "Unban"
},
"banModal": {
"title": "Ban IP Address",
"ipLabel": "IP Address",
"durationLabel": "Duration",
"duration1h": "1 hour",
"duration4h": "4 hours",
"duration24h": "24 hours",
"duration7d": "7 days",
"duration30d": "30 days",
"durationPermanent": "Permanent",
"reasonLabel": "Reason",
"reasonPlaceholder": "Reason for banning this IP...",
"submit": "Ban IP"
},
"unbanModal": {
"title": "Confirm Unban",
"confirm": "Are you sure you want to unban",
"submit": "Unban"
}
},
"smtp": {
"title": "Email (SMTP) Settings",
"description": "Configure SMTP settings to enable email notifications and user invitations.",
"configuration": "SMTP Configuration",
"configDescription": "Enter your SMTP server details to enable email functionality.",
"host": "SMTP Host",
"port": "Port",
"username": "Username",
"password": "Password",
"passwordHelper": "Use app-specific password for Gmail",
"fromAddress": "From Address",
"encryption": "Encryption",
"selectEncryption": "Select encryption",
"starttls": "STARTTLS (Recommended)",
"sslTls": "SSL/TLS",
"none": "None",
"testConnection": "Test Connection",
"saveSettings": "Save Settings",
"settingsSaved": "SMTP settings saved successfully",
"saveFailed": "Failed to save SMTP settings",
"connectionSuccess": "SMTP connection successful",
"connectionFailed": "SMTP connection failed",
"testFailed": "Failed to test SMTP connection",
"configured": "SMTP Configured",
"notConfigured": "SMTP Not Configured",
"active": "Active",
"inactive": "Inactive",
"sendTestEmail": "Send Test Email",
"testEmailDescription": "Send a test email to verify your SMTP configuration is working correctly.",
"sendTest": "Send Test",
"testEmailSent": "Test email sent successfully",
"testEmailFailed": "Failed to send test email",
"needHelp": "Need Help?",
"helpText": "If you're using Gmail, you'll need to enable 2-factor authentication and create an app-specific password. For other providers, check their SMTP documentation for the correct settings."
},
"securityHeaders": {
"title": "Security Headers",
"description": "Configure HTTP security headers for your proxy hosts",
"createProfile": "Create Profile",
"alertTitle": "Secure Your Applications",
"alertDescription": "Security headers protect against common web vulnerabilities. Use presets for quick setup or create custom profiles for fine-grained control.",
"systemProfiles": "System Profiles (Read-Only)",
"systemProfilesDescription": "Pre-configured security profiles you can assign to proxy hosts. Clone to customize.",
"customProfiles": "Custom Profiles",
"noCustomProfiles": "No custom profiles yet",
"noCustomProfilesDescription": "Create a custom security header profile or apply a preset to get started",
"view": "View",
"clone": "Clone",
"updated": "Updated",
"viewProfile": "View Security Header Profile",
"editProfile": "Edit Security Header Profile",
"createProfileTitle": "Create Security Header Profile",
"confirmDeletion": "Confirm Deletion",
"deleteConfirmMessage": "Are you sure you want to delete \"{{name}}\"? A backup will be created before deletion.",
"deleting": "Deleting...",
"creatingBackup": "Creating backup before deletion...",
"backupCreated": "Backup created",
"backupFailed": "Failed to create backup",
"deleteSuccess": "\"{{name}}\" deleted. A backup was created before deletion.",
"deleteFailed": "Failed to delete: {{error}}",
"presets": {
"basic": "Minimal security headers for maximum compatibility.\n✓ Best for: Testing, development, simple websites.\n✓ Compatible with all applications and mobile apps.",
"apiFriendly": "Optimized for mobile apps and API clients.\n✓ Best for: Radarr, Sonarr, Plex, Jellyfin, Home Assistant, Vaultwarden.\n✓ Strong transport security, allows cross-origin access.\nRecommended for services accessed by mobile apps.",
"strict": "Strong security for web applications.\n✓ Best for: Web-only dashboards, admin panels.\n⚠ May break mobile apps and API clients.\nNot recommended for Radarr, Plex, or services with companion apps.",
"paranoid": "Maximum security for high-risk applications.\n✓ Best for: Banking, healthcare, compliance-critical apps.\n⚠ WILL break mobile apps, API clients, and OAuth flows.\nOnly use if you understand and can customize every header."
}
},
"dns": {
"title": "DNS Management",
"description": "Manage DNS providers and plugins for certificate automation"
},
"dnsProviders": {
"title": "DNS Providers",
"description": "Manage DNS providers for wildcard certificate validation",
"note": "DNS Provider Information",
"noteText": "DNS providers are required to issue wildcard certificates (e.g., *.example.com) via Let's Encrypt DNS-01 challenge. Configure at least one provider to enable wildcard domain support.",
"addProvider": "Add DNS Provider",
"addFirstProvider": "Add Your First DNS Provider",
"editProvider": "Edit DNS Provider",
"deleteProvider": "Delete DNS Provider",
"noProviders": "No DNS Providers Configured",
"noProvidersDescription": "Add a DNS provider to enable wildcard certificate issuance for your domains.",
"providerName": "Provider Name",
"providerNamePlaceholder": "e.g., Production Cloudflare",
"providerType": "Provider Type",
"selectProviderType": "Select a DNS provider...",
"selectProvider": "Select DNS provider...",
"noProvider": "None (HTTP-01 Challenge)",
"noProvidersAvailable": "No providers available",
"credentials": "Credentials",
"viewDocs": "View Documentation",
"testConnection": "Test Connection",
"advancedSettings": "Advanced Settings",
"propagationTimeout": "Propagation Timeout (seconds)",
"propagationTimeoutHint": "Maximum time to wait for DNS propagation (30-600s)",
"pollingInterval": "Polling Interval (seconds)",
"pollingIntervalHint": "How often to check for DNS record propagation (1-60s)",
"setAsDefault": "Set as default provider",
"active": "Active",
"error": "Error",
"unconfigured": "Unconfigured",
"default": "Default Provider",
"lastUsed": "Last Used",
"neverUsed": "Never used",
"successRate": "Success / Failures",
"lastError": "Last Error",
"createSuccess": "DNS provider created successfully",
"updateSuccess": "DNS provider updated successfully",
"deleteSuccess": "DNS provider deleted successfully",
"deleteFailed": "Failed to delete DNS provider",
"deleteConfirmation": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.",
"testSuccess": "Connection test successful",
"testFailed": "Connection test failed",
"types": {
"cloudflare": "Cloudflare",
"route53": "Amazon Route 53",
"digitalocean": "DigitalOcean",
"googleclouddns": "Google Cloud DNS",
"namecheap": "Namecheap",
"godaddy": "GoDaddy",
"azure": "Azure DNS",
"hetzner": "Hetzner",
"vultr": "Vultr",
"dnsimple": "DNSimple",
"manual": "Manual (No Automation)",
"webhook": "Webhook (HTTP)",
"rfc2136": "RFC 2136 (Dynamic DNS)",
"script": "Script (Shell)"
},
"categories": {
"builtIn": "Built-in Providers",
"custom": "Custom Integrations"
}
},
"dnsProvider": {
"manual": {
"title": "Manual DNS Challenge",
"instructions": "To obtain a certificate for {{domain}}, create the following TXT record at your DNS provider:",
"createRecord": "Create this TXT record at your DNS provider",
"recordName": "Record Name",
"recordValue": "Record Value",
"recordType": "Record Type",
"ttl": "TTL",
"seconds": "seconds",
"minutes": "minutes",
"timeRemaining": "Time remaining",
"progressPercent": "{{percent}}% time remaining",
"challengeProgress": "Challenge timeout progress",
"copy": "Copy",
"copied": "Copied!",
"copyFailed": "Failed to copy to clipboard",
"copyRecordName": "Copy record name to clipboard",
"copyRecordValue": "Copy record value to clipboard",
"checkDnsNow": "Check DNS Now",
"checkDnsDescription": "Immediately check if the DNS record has propagated",
"verifyButton": "I've Created the Record - Verify",
"verifyDescription": "Verify that the DNS record exists and complete the challenge",
"cancelChallenge": "Cancel Challenge",
"lastCheck": "Last checked",
"lastCheckSecondsAgo": "{{seconds}} seconds ago",
"lastCheckMinutesAgo": "{{minutes}} minutes ago",
"notPropagated": "DNS record not yet propagated",
"dnsNotFound": "DNS record not found. Please ensure the TXT record is created correctly.",
"verifySuccess": "DNS challenge verified successfully!",
"verifyFailed": "DNS verification failed",
"challengeExpired": "Challenge expired. Please try again.",
"challengeCancelled": "Challenge cancelled",
"cancelFailed": "Failed to cancel challenge",
"statusChanged": "Challenge status changed to {{status}}",
"status": {
"created": "Created",
"pending": "Pending",
"verifying": "Verifying...",
"verified": "Verified",
"expired": "Expired",
"failed": "Failed"
},
"statusMessage": {
"created": "Challenge created. Create the DNS record to continue.",
"pending": "Waiting for DNS propagation...",
"verifying": "Verifying DNS record...",
"verified": "DNS challenge verified successfully!",
"expired": "Challenge has expired. Please start a new challenge.",
"failed": "DNS verification failed. Please check the record and try again."
}
}
},
"dns_detection": {
"detecting": "Detecting DNS provider...",
"detected": "{{provider}} detected",
"confidence_high": "High confidence",
"confidence_medium": "Medium confidence",
"confidence_low": "Low confidence",
"confidence_none": "No match",
"not_detected": "Could not detect DNS provider",
"use_suggested": "Use {{provider}}",
"select_manually": "Select manually",
"nameservers": "Nameservers",
"error": "Detection failed: {{error}}",
"wildcard_required": "Auto-detection works with wildcard domains (*.example.com)"
},
"plugins": {
"title": "DNS Provider Plugins",
"description": "Manage built-in and external DNS provider plugins for certificate automation",
"note": "Note",
"noteText": "External plugins extend Charon with custom DNS providers. Only install plugins from trusted sources.",
"builtInPlugins": "Built-in Providers",
"externalPlugins": "External Plugins",
"noPlugins": "No Plugins Found",
"noPluginsDescription": "No DNS provider plugins are currently installed.",
"addPlugin": "Add Plugin",
"reloadPlugins": "Reload Plugins",
"reloadSuccess": "Plugins reloaded: {{count}} loaded",
"reloadFailed": "Failed to reload plugins",
"pluginDetails": "Plugin Details",
"cannotDisableBuiltIn": "Built-in plugins cannot be disabled",
"enableSuccess": "Plugin enabled successfully",
"disableSuccess": "Plugin disabled successfully",
"toggleFailed": "Failed to toggle plugin",
"type": "Type",
"status": "Status",
"version": "Version",
"author": "Author",
"pluginType": "Plugin Type",
"builtIn": "Built-in",
"external": "External",
"loadedAt": "Loaded At",
"description": "Description",
"documentation": "Documentation",
"errorDetails": "Error Details",
"details": "Details",
"docs": "Docs",
"loaded": "Loaded",
"error": "Error",
"pending": "Pending",
"disabled": "Disabled"
},
"encryption": {
"title": "Encryption Key Management",
"description": "Manage encryption keys and rotate DNS provider credentials",
"currentVersion": "Current Key Version",
"versionNumber": "Version {{version}}",
"activeEncryptionKey": "Active encryption key",
"providersUpdated": "Providers Updated",
"providersOnCurrentVersion": "Using current key version",
"providersOutdated": "Providers Outdated",
"providersNeedRotation": "Need key rotation",
"nextKey": "Next Key",
"configured": "Configured",
"notConfigured": "Not Configured",
"nextKeyDescription": "Ready for rotation",
"legacyKeysDetected": "Legacy Encryption Keys Detected",
"legacyKeysMessage": "{{count}} legacy keys are configured for backward compatibility. These can be removed after 30 days.",
"actions": "Key Management Actions",
"actionsDescription": "Rotate encryption keys or validate configuration",
"rotateKey": "Rotate Encryption Key",
"rotating": "Rotating...",
"validateConfig": "Validate Configuration",
"validating": "Validating...",
"nextKeyRequired": "To rotate keys, configure CHARON_ENCRYPTION_KEY_V2 environment variable and restart the application.",
"rotationInProgress": "Rotation in progress...",
"environmentGuide": "Environment Variable Configuration",
"environmentGuideDescription": "How to configure encryption keys for rotation",
"step1": "Step 1",
"step1Description": "Set CHARON_ENCRYPTION_KEY_V2 with new key",
"step2": "Step 2",
"step2Description": "Restart application to load both keys",
"step3": "Step 3",
"step3Description": "Trigger rotation via this UI",
"step4": "Step 4",
"step4Description": "Rename V2 → CHARON_ENCRYPTION_KEY, old key → V1, then restart",
"retentionWarning": "Keep old encryption keys configured for at least 30 days to allow for rollback if needed.",
"rotationHistory": "Rotation History",
"rotationHistoryDescription": "Recent key rotation operations",
"date": "Date",
"actor": "Actor",
"action": "Action",
"details": "Details",
"confirmRotationTitle": "Confirm Key Rotation",
"confirmRotationMessage": "This will re-encrypt all DNS provider credentials with the new key. This operation cannot be undone.",
"rotationWarning1": "All credentials will be re-encrypted. Ensure CHARON_ENCRYPTION_KEY_V2 is properly configured.",
"rotationWarning2": "The application should remain online during rotation. Backup your database before proceeding.",
"confirmRotate": "Start Rotation",
"rotationSuccess": "Key rotation completed successfully: {{count}}/{{total}} providers rotated in {{duration}}",
"rotationPartialFailure": "Warning: {{count}} providers failed to rotate. Check audit logs for details.",
"rotationError": "Key rotation failed: {{error}}",
"validationSuccess": "Key configuration is valid and ready for rotation",
"validationError": "Key configuration validation failed. Check errors below.",
"validationFailed": "Validation request failed: {{error}}",
"failedToLoadStatus": "Failed to load encryption status. Please refresh the page."
}
}