happyDomain/web/src/lib/locales/en.json
Pierre-Olivier Mercier d57c0849a6 compliance: MX record sync validators
Validates a MX record set (svcs.MXs) at edit time:

- Null MX (RFC 7505): a "." target must be the only MX in the set, with
  preference 0. Both deviations are surfaced.
- Targets: invalid hostnames, out-of-range preferences (uint16) and
  duplicate targets (case-insensitive on the FQDN).
- Cross-zone: flags MX targets that are CNAME owners in the same zone
  (RFC 5321 sec. 5.1) and warns when an in-zone target lacks any
  A/AAAA service. External targets are left to runtime checkers.

Unit tests cover happy paths, the null-MX edge cases, target/preference
validation, duplicate detection and the in-zone cross checks (CNAME
collision, missing address, apex target).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:52:30 +07:00

1248 lines
62 KiB
JSON
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"account": {
"ask-have": "Don't already have an account on our beautiful platform?",
"delete": {
"delete": "Dangerous zone",
"delete-button": "Delete my account",
"deleted": "Account Deleted",
"description": "Permanently delete your account",
"confirm": "If you want to delete your account and all data associated with it, press the delete button:",
"confirm-twice": "By confirming the deletion, you will permanently and irrevocably delete your account from our database and will loose your access to our easy management interface for your domains.",
"confirm-password": "To ensure this is really you, please enter your password:",
"consequence": "Your domains owned on others platforms will not be affected by the deletion, they'll continue to respond with the current dataset.",
"remain-data": "For technical reason, your account will be deleted right after your validation, but some data from your account will persist until the next database clean up.",
"success": "Your account have been successfully deleted. We hope to see you back soon."
},
"join": "Join now!",
"no-password-change": "You are identified through an external service, if you need to change your password, change it on the dedicated interface of {{provider}}.",
"oidc-login": "Sign in with {{provider}}",
"ready-login": "Ready to login!",
"signup": {
"already": "Already a member?",
"join-call": "Join our nice platform in less than 2 minutes!",
"address-why": "We'll use your address to {{identify}} you on this platform, and to contact you for {{security-operations}}.",
"identify": "identify",
"security-operations": "security related reasons",
"receive-update": "Keep me informed of future big improvements",
"signup": "Sign up!",
"success": "Registration successfully performed!",
"login-now": "You can now login with your credentials."
}
},
"common": {
"add": "Add",
"add-new-thing": "Add new {{thing}}",
"add-object": "Add a {{thing}} object to this service",
"cancel": "Cancel",
"copy-clipboard": "Copy to clipboard",
"continue": "Continue",
"create-thing": "Create {{thing}}",
"delete": "Delete",
"domain": "Domain or subdomain",
"edit": "Edit",
"field": "Field",
"filter": "Filter",
"go": "Go!",
"go-back": "Go Back",
"got-it": "Got it!",
"next": "Next",
"no-content": "No content",
"no-thing": "No {{thing}}",
"new-row": "New row",
"other": "Other",
"password": "Password",
"previous": "Previous",
"rename": "Rename",
"resolver": "Resolver",
"run": "Run the request!",
"survey": "A remark? A comment to share? Don't hesitate to write to us!",
"update": "Update",
"update-what": "Update {{what}}",
"welcome": {
"start": "Welcome to ",
"end": "!"
},
"help": "Help!",
"records": "{{n:eq; 0:no {{type}} record; 1:{{type}} record; default:{{type}} records}}"
},
"domains": {
"title": "Your domains",
"description": "Browse and manage all your domain names in one place",
"kind": "domain",
"subdomain": "subdomain",
"actions": {
"audit": "View changes logs",
"checks": "Domain checks",
"history": "View changes history",
"propagate": "Publish my changes",
"reimport": "Fetch current deployed zone",
"rollback": "Roll back to this version",
"share": "Share the zone…",
"upload": "Import a zone file",
"view": "View my zone",
"whois": "View registration data",
"others": "More actions on {{domain}}"
},
"alert": {
"remove": "This action only removes {{domain}} from your happyDomain managed domains. All history and abstracted zones will be discarded. The domain {{domain}} remains fully intact at the provider. Are you sure you want to continue?"
},
"and-more-filtered": "{{count:eq; 0:no more filtered domain; 1:1 more filtered domain; default:{{count}} more filtered domains}}",
"add-a-subdomain": "Add a subdomain",
"add-a-service": "Add a service",
"add-alias": "Add alias",
"add-an-alias": "Add an alias to {{domain}}",
"add-title": "New Domain",
"add-now": "Add it now!",
"search-placeholder": "Search domains…",
"create-on-provider": "Create on {{provider}}",
"added-success": "Great! {{domain}} has been added. You can manage it right now.",
"apply": {
"additions": "{{count:eq; 0:no additions; 1:{{count}} addition; default:{{count}} additions}}",
"button": "Apply modifications",
"deletions": "{{count:eq; 0:no deletions; 1:{{count}} deletion; default:{{count}} deletions}}",
"double-check": "You see this confirmation dialog because you choose in your preference to always confirm before applying corrections.",
"modifications": "{{count:eq; 0:no modification; 1:{{count}} modification; default:{{count}} modifications}}",
"nochange": "There is no changes to apply! Current zone is in sync with the server.",
"change-already-applied": "Changes you requested seems to be already applied.",
"others": "{{count:eq; 0:no other change; 1:{{count}} other change; default:{{count}} others changes}}",
"prepare-info": "The provider will execute {{nbDiffs}} correction(s) for your {{nbSelected}} selected change(s):",
"prepare-warning": "The number of corrections differs from your selection. Please review before confirming.",
"confirm": "Confirm & Apply",
"back": "Back"
},
"attached-new": "New domain attached to happyDomain!",
"commit-msg": "What's changed?",
"create-new-key": "Create new {{id}} key",
"discard": "Discard",
"drop-alias": "Drop alias",
"drop-pointer": "Drop pointer",
"edit-target": "Edit target",
"give-explicit-name": "Give an explicit name in order to easily find this service.",
"n-aliases": "{{count:lt; 2:{{count}} alias; default:{{count}} aliases}}",
"n-services": "{{count:lt; 2:{{count}} service; default:{{count}} services}}",
"filtered-no-result": "There is no domain with those filters.",
"please-fill-fields": "Please fill the following fields:",
"removal": "Confirm Domain Removal",
"save-modifications": "Save those modifications",
"stop": "Stop managing this domain",
"view": {
"cancel-title": "Keep my domain in happyDomain",
"description": "Review the modifications that will be applied to {{domain}}",
"provider": "Zone hosted on",
"title": "View zone",
"subtitle": "Your zone in standard BIND format"
},
"alias-creation": "Add an alias pointing to {{domain}}:",
"alias-creation-sample": "This will create the alias:",
"placeholder-search": "my.domain.",
"placeholder-new": "my.new.domain.",
"placeholder-new-sub": "new.subdomain",
"form-new-subdomain": "Add a new subdomain under {{domain}}:"
},
"domaingroups": {
"all": "All groups",
"manage": "Manage your domain groups",
"new": "New group",
"drop-here": "Drop a domain here",
"no-group": "Miscellaneous",
"title": "Your groups"
},
"email": {
"address": "Email address",
"instruction": {
"bad-link": "The link you followed is invalid. Check that you copied the entire link and retry.",
"check-inbox": "Please check your inbox in order to validate your e-mail address.",
"new-confirmation": "If you need a new confirmation e-mail, just enter your address in the form below.",
"validate-address": "In order to validate your e-mail address, please check your inbox, and follow the link contained in the message.",
"validated": "Your new e-mail address is now validated!"
},
"send-again": "Re-send the confirmation e-mail",
"send-recover": "Send me an e-mail to recover my account",
"sent": "Confirmation e-mail sent!",
"sent-recovery": "Password recovery email sent!",
"recover": "In order to recover your account, we'll send you an e-mail containing a link that will allow you to redefine your password",
"validation-unavailable": {
"title": "Email Validation Unavailable",
"description": "The email functionality has been disabled on this server. Please contact your administrator for assistance."
}
},
"captcha": {
"human-check": "Are you a human? Please check the box below to continue:"
},
"domaininfo": {
"page-title": "Registration Data Lookup",
"page-description": "Look up registration information for any domain name",
"domain-description": "Enter the domain name you want to look up, e.g. {{domain}}.",
"lookup": "Look up",
"registrar": "Registrar",
"registrar-url": "Registrar website",
"nameservers": "Nameservers",
"creation-date": "Registered on",
"expiration-date": "Expires on",
"status": "Domain status",
"no-expiration": "No expiration date available",
"no-creation": "No registration date available",
"no-registrar": "Unknown registrar",
"expires-in": "Expires in {{days}} days",
"expired": "Expired {{days}} days ago",
"expires-today": "Expires today",
"domain-not-found": "This domain name does not appear to be registered.",
"error": "Could not retrieve domain information.",
"status-descriptions": {
"ok": "The domain is active with no restrictions.",
"active": "The domain is active.",
"clientTransferProhibited": "Transfer to another registrar is locked.",
"serverTransferProhibited": "Transfer is prohibited by the registry.",
"clientUpdateProhibited": "Domain updates are locked.",
"serverUpdateProhibited": "Domain updates are prohibited by the registry.",
"clientDeleteProhibited": "Domain deletion is locked.",
"serverDeleteProhibited": "Domain deletion is prohibited by the registry.",
"clientHold": "The domain is on hold (not resolving).",
"serverHold": "The domain is on hold by the registry.",
"pendingTransfer": "A transfer to another registrar is pending.",
"pendingDelete": "The domain is pending deletion."
}
},
"errors": {
"404": {
"title": "Page not found",
"content": "The page you are looking for was not found."
},
"account-delete": "An error occurs when trying to delete your account",
"address": "Email address is required",
"address-valid": "A valid email address is required",
"domain-have": "It appears you don't have any domain name registered on this provider.",
"domain-import": "An error occurs when trying to synchronize this domain:",
"domain-list": "This provider doesn't permit to list existing domains. Use the above form to add one.",
"login": "Login error",
"rate-limited": "Too many failed login attempts. Please wait a moment before trying again.",
"logout": "Logout error",
"password": "Password is required",
"password-change": "Unable to change your password account",
"password-match": "Password and its confirmation doesn't match.",
"password-weak": "Password needs to be stronger: at least 8 characters with numbers, lower case and upper case characters.",
"recovery": "Password recovery problem",
"resolve": "An error occurs when trying to resolve the domain.",
"registration": "Registration problem",
"session": {
"title": "Authentication timeout",
"content": "Invalid session, you have been logged out: {{err}}. Please login again."
},
"settings-change": "Unable to change your settings",
"account-no-auth": "You're using happyDomain without authentication. You cannot manage other account properties.",
"domain-all-imported": "This account on {{provider}} doesn't have any more domain to import.",
"too-high": "Number too high, max: {{max}}",
"too-low": "Number too low, min: {{min}}",
"base64": "Invalid base64 string.",
"base64-illegal-char": "Illegal character used.",
"base64-unfinished": "Unfinished string.",
"suggestion": "Did you mean: {{suggestion}}"
},
"history": {
"committed-on": "Committed on",
"created-on": "Created on",
"diff": "View differences",
"expires-on": "Expires on",
"modified-on": "Modified on",
"published-on": "Published on",
"see": "Display the zone at this time",
"title": "History of changes to the zone ",
"subtitle": "Browse all past versions of your zone",
"used-on": "Last used on"
},
"logs": {
"date": "Date",
"description": "Action/description",
"level": "Level",
"no-entry": "No entry in the domain log.",
"title": "Domain's logs ",
"subtitle": "A full trace of all activity on this domain",
"user": "User"
},
"menu": {
"my-domains": "My domains",
"my-providers": "My domain providers",
"dns-resolver": "DNS resolver",
"whois": "Registration Data Lookup",
"checkers": "Configure Checkers",
"my-account": "My account",
"logout": "Sign out",
"provider-features": "Supported providers",
"signup": "Sign up",
"signin": "Sign in",
"quick-menu": "Quick Access"
},
"onboarding": {
"steps": {
"welcome": "Welcome",
"connect": "Connect Domain Provider",
"import": "Import Domains",
"explore": "Explore Features"
},
"intro": "Let's set up your account and start managing your domains. Follow these simple steps to get started.",
"welcome": {
"beta": {
"intro": "It's beta software! 🏗️",
"part1": "happyDomain is functional but still very much a work in progress. If something doesn't work, please",
"report": "tell us what's wrong",
"part2": ". We're highly responsive and each reported bug helps us improve the tool for everyone. Thanks in advance 🙏"
},
"purpose": "{{happyDomain}} makes domain management simple and intuitive. Whether you have one domain or hundreds, our platform gives you a centralized way to manage them all.",
"use": "Use {{happyDomain}} as a replacement interface to your usual domain name provider. It'll still rely on your provider's infrastructure, via our simple interface.",
"unified": {
"title": "Unified Management",
"description": "Manage all your domains in one place, regardless of where they're registered."
}
},
"connect": {
"title": "Connect Your First Domain Provider",
"intro": "Connect your domain registrar or DNS provider to import your domains automatically. We support most major providers.",
"noprovider": "Can't find your provider in this list?",
"noproviderTellUs": "Tell us what's yours",
"nodomain": "I don't own any domain yet"
},
"import": {
"title": "Import Your Domains",
"intro": "Select the domains you want to manage with happyDomain.",
"imported": "Imported"
},
"explore": {
"understood": "Understood!",
"done": "You're all set!",
"bravo": "{{count:eq; 1:Your domain is; default:Your domains are}} now properly configured and ready to use.",
"title": "Explore happyDomain Features",
"intro": "Now that your domain is set up, discover all the powerful features happyDomain has to offer:",
"history": {
"title": "Record History",
"description": "Track all changes made to your DNS records with version history and rollback options.",
"link": "View history"
},
"api": {
"title": "API Access",
"description": "Automate domain management with our comprehensive API for developers and teams.",
"link": "API Documentation"
},
"monitoring": {
"title": "Monitoring",
"description": "Real-time monitoring of your domains with alerts for any issues or expirations."
},
"security": {
"title": "Security Check",
"description": "Automated security audits to ensure your domain configurations follow best practices."
},
"soon": "soon"
},
"no-sale": {
"title": "You need to own a domain to use happyDomain.",
"description": "{{happyDomain}} does not sell domains yet. To start using our interface, you need to buy a domain from one of our supported providers.",
"buy-advice": "We'll provide some guidance in the near future on how to easily buy a domain name. So stay tuned and get in touch with us if you can help us build a comprehensive guide."
}
},
"password": {
"change": "Change my password",
"changed": "Password Successfully Changed",
"confirm-title": "Confirm New Password",
"confirm-description": "Re-enter your new password to confirm",
"confirmation": "Password confirmation",
"current-title": "Current Password",
"current-description": "Enter your current password to verify your identity",
"new-title": "New Password",
"new-description": "Choose a strong password with at least 8 characters, including numbers, lowercase and uppercase letters",
"fill": "In order to recover your account, please fill the following form, with a fresh password.",
"forgotten": "Forgotten password?",
"new": "New password",
"redefine": "Redefine my password",
"redefined": "Password redefined successfully!",
"recovery-unavailable": {
"title": "Password Recovery Unavailable",
"description": "The email functionality has been disabled on this server. Please contact your administrator to reset your password."
},
"success": "You can now login with your new password.",
"success-change": "Your account's password has been changed with success."
},
"resources": {
"CAA": {
"all-issuers-title": "All issuers authorized.",
"all-issuers-body": "With those parameters, all issuer can create certificate for this domain and subdomain.",
"all-wild-issuers-body": "With those parameters, all issuer can create wildcard certificate for this domain and subdomain.",
"auth-issuers": "Authorized Issuers",
"incident-response": "Incident Response",
"incident-response-text": "How would you want to be contacted in case of violation of the current security policy?",
"mail-issuers": "S/MIME certificates issuance",
"mail-all-allowed-title": "No CA constraint for S/MIME certificates issuance.",
"mail-all-allowed-body": "All CA can emit S/MIME certificates for your domain. You should disallow or restrict to certain CA. S/MIME certificates are used for example to sign and encrypt e-mail communications. If you do not use such certificate, you should disallow their issuance.",
"no-issuers-hint": "Disallow any certificate issuance",
"no-issuers-title": "No issuer authorized.",
"no-issuers-body": "With those parameters, no issuer is allowed to create certificate for this subdomain.",
"no-mail-hint": "Disallow S/MIME certificate issuance",
"no-mail-title": "No issuer authorized for S/MIME certificate.",
"no-mail-body": "With those parameters, no issuer is authorized to create S/MIME certificate for this domain and subdomain.",
"no-wild-hint": "Disallow wildcard certificate issuance",
"no-wild-title": "No wildcard issuer authorized.",
"no-wild-body": "With those parameters, no issuer is authorized to create wildcard certificate for this domain and subdomain. But this can be override with the following settings:",
"title": "Certificates issuance",
"wild-issuers": "Wildcard certificates issuance",
"wild-same-title": "Same as regular certificate issuance.",
"wild-same-body": "With those parameters, all issuer authorized for certificate issuance can also create wildcard certificate for this domain and subdomain.",
"vmc-issuers": "Verified Mark Certificates (VMC) issuance",
"no-vmc-hint": "Disallow VMC certificate issuance",
"vmc-all-allowed-title": "No CA constraint for VMC certificates issuance.",
"vmc-all-allowed-body": "All CA can emit VMC certificates for your domain. VMC certificates are used to display verified logos in email clients. If you do not use such certificate, you should disallow their issuance.",
"no-vmc-title": "No issuer authorized for VMC certificate.",
"no-vmc-body": "With those parameters, no issuer is authorized to create VMC certificate for this domain and subdomain.",
"contact-info": "Contact Information",
"contact-info-text": "Provide contact details for certificate-related communications.",
"contact-email": "Contact Email",
"contact-phone": "Contact Phone",
"add-contact-email": "Add contact email",
"add-contact-phone": "Add contact phone"
}
},
"service": {
"add": "Add service",
"all": "All",
"delete": "Delete this service",
"edit": "Edit this service",
"update": "Update this service",
"form-new": "Add a new service to {{domain}}",
"new": "New service",
"new-description": "Click here to add a new service to this subdomain.",
"default-ttl": "Default TTL",
"ttl": "TTL",
"ttl-long": "Time-To-Live",
"ttl-tip": "0 means default TTL, others values are exprimed in seconds",
"propagating": "Propagating {{countdown}}",
"propagation-in-progress": "DNS propagation in progress",
"propagation-remaining": "Propagation complete in {{countdown}}"
},
"records": {
"add": "Add record",
"class": "Class",
"delete": "Delete this record",
"update": "Update this record",
"form-new": "Add a new record to {{domain}}",
"rrtype": "type",
"ttl": "Time-to-live"
},
"sessions": {
"close-all": "Terminate all sessions",
"create": "Create API key",
"current": "current session",
"description": "Name your session",
"secret": "Session secret",
"usage": "Here is an example on how to use the generated secret:"
},
"provider": {
"all": "All providers",
"another": "Use another provider",
"associations": "{{count:eq; 0:no domain associated; 1:{{count}} domain associated; default:{{count}} domains associated}}",
"check-config": "Check your provider configuration",
"description": "Manage your DNS provider connections and credentials",
"delete": "Delete this domain provider",
"empty": "You have no provider defined currently. Try {{action}}!",
"empty-action": "adding one",
"name-your": "Name your domain provider",
"no-name": "No name",
"provider": "Domains living on {{provider}}",
"kind": "domain provider",
"select-provider": "Select the DNS provider hosting your zone:",
"provider-name": "Host's name",
"provider-type": "Hosting provider type",
"title": "Your domain providers",
"import-domains": "Import all domains",
"new-form": "New domain provider form",
"linked-domains": "Linked domains",
"update": "Update domain provider"
},
"upgrade": {
"title": "An update is available!",
"content": "A new version of happyDomain is already available. To enable it, please click here to refresh the page."
},
"wait": {
"asking-domains": "Asking provider for the existing domains...",
"exporting": "Please wait while we export your zone…",
"formating": "Please wait while we format your zone…",
"importing": "Please wait while we are importing your domain…",
"loading": "Loading domain's services…",
"retrieving-setting": "Retrieving host settings' form...",
"updating": "Updating your domain name host",
"wait": "Please wait",
"retrieving-domains": "Retrieving your domains...",
"retrieving-provider": "Retrieving hosting provider information...",
"retrieving-providers": "Retrieving your providers...",
"preparation": "Preparing changes…",
"propagation": "Publishing your changes…"
},
"settings": {
"subtitle": "Tailor your happyDomain experience to your needs",
"fieldhint": {
"title": "Field hints",
"description": "Choose how to display help text for form fields",
"hide": "Hide",
"tooltip": "Tooltip near field",
"focused": "Under field when focused",
"always": "Under field, always"
},
"language": "Language",
"language-description": "Choose your preferred language for the interface",
"save": "Save settings",
"showrrtypes-title": "Show DNS record types",
"preferences": {
"title": "Preferences",
"description": "Customize your preferences"
},
"security": {
"title": "Security & Access",
"description": "Manage your authentication and security settings",
"sessions": {
"title": "Active Sessions"
},
"password": {
"description": "Set a new password for your account"
}
},
"showrrtypes": "Show resource type associated with services (for users familiar with DNS)",
"success": "Continue to enjoy happyDomain.",
"success-change": "Your settings has been saved.",
"title": "Settings",
"applyconfirm": {
"title": "Confirmation before applying",
"description": "Choose when to show a confirmation step before applying changes to your DNS provider",
"unexpected": "Ask on unexpected differences",
"always": "Always ask",
"never": "Never ask, overwrite on publish"
},
"zoneview": {
"grid": "Grid view (easiest)",
"list": "List view (fastest)",
"records": "List with records (advanced)",
"title": "Zone view layout",
"description": "Choose how you want to display your domain zones"
}
},
"record": {
"A": "IPv4 address",
"AAAA": "IPv6 address",
"common-records": "Common types",
"Expire": "Expire",
"Mbox": "Administration e-mail",
"Minttl": "Negative cache TTL",
"Mx": "Mail server",
"Ns": "Name server",
"Preference": "Preference",
"Priority": "Priority",
"Refresh": "Refresh",
"Retry": "Retry",
"Serial": "Serial",
"Target": "Target",
"Txt": "Data",
"Weight": "Weight"
},
"resolver": {
"advanced": "With custom settings?",
"custom": "Custom resolver",
"custom-description": "Enter the addresse (a domain name or an IP) of the resolver you want to use.",
"domain-description": "Indicate the domain you search the records. For example, you can try {{domain}}.",
"error-description": "The DNS query could not be completed due to an error.",
"field-description": "What kind of DNS record you want to see. For example: A is for IPv4, AAAA is for IPv6, ...",
"no-answer": "The DNS query completed successfully, but no records were found for this domain and type.",
"no-records-description": "Your query returned no results.",
"page-description": "Query DNS records for any domain",
"query-failed": "Query Failed",
"query-results": "Query Results",
"resolver-description": "This is the server we will ask for the information.",
"results-description": "DNS records found for {{domain}} ({{type}} records)",
"results-description-default": "DNS records found for your query",
"ttl": "Remaining time in cache",
"showDNSSEC": "Show DNSSEC records in answer (if any)"
},
"generator": {
"title": "DNS Record Generators",
"description": "Free online DNS record generators: CAA, DMARC, SPF, MX, DKIM, SRV, and more. Build and preview DNS zone records instantly.",
"subtitle": "Pick a record type to build and preview its DNS zone entry — no account needed.",
"icon-alt": "{{name}} icon",
"svctype": {
"title": "{{name}} Generator",
"page-title": "DNS Record Generator",
"description": "Free online {{name}} DNS record generator. Configure and preview your {{name}} record in zone file format.",
"not-found": "Service type <code>{{svctype}}</code> not found.",
"domain-settings": "Your Domain Name",
"domain-help": "Enter the domain name where the record will be created. The generated records will use this domain.",
"configure-record": "Fill the Required Information",
"generated-records": "Get the Generated DNS Records",
"fill-form": "Fill in the form above to generate records.",
"generating": "Generating…",
"no-records": "No records generated.",
"cta-title": "Handle DNS complexity with happyDomain",
"cta-text": "happyDomain lets you manage all your DNS records through a visual interface — no zone file editing required.",
"cta-button": "Create a free account"
}
},
"zones": {
"viewer": "Zone Viewer",
"viewer-subtitle": "Your services at a glance",
"retrieve": "Retrieving Zone",
"retrieve-subtitle": "Fetching DNS records from your provider",
"upload": "Import a zone",
"import-text": "Import from text",
"import-file": "Import from file",
"return-to": "Go to the zone",
"return-to-results": "Back to results"
},
"checkers": {
"run-check": {
"title": "Run Check",
"loading-options": "Loading checker options...",
"configure-info": "Configure checker options below. Pre-filled values are from domain-level settings.",
"no-options": "This checker has no configurable options. Click \"Run Check\" to execute with default settings.",
"no-run-options": "This checker has no run-time options. You can still override advanced settings below.",
"error-loading-options": "Error loading checker options: {{error}}",
"run-button": "Run Check",
"triggered-success": "Check triggered successfully! Execution ID: {{id}}",
"trigger-failed": "Failed to trigger check: {{error}}",
"advanced-options": "Advanced options",
"rules": "Rules"
},
"never": "Never",
"status": {
"ok": "OK",
"info": "Info",
"warning": "Warning",
"critical": "Critical",
"error": "Error",
"unknown": "Unknown",
"planned": "Planned",
"running": "Running",
"not-run": "Not run"
},
"list": {
"title": "Checks for ",
"loading": "Loading checkers...",
"no-checks": "No checks available for this domain.",
"view-results": "View Results",
"prometheus-metrics": "Prometheus Metrics",
"prometheus-metrics-copied": "Prometheus metrics URL copied to clipboard",
"prometheus-metrics-copy-failed": "Failed to copy Prometheus metrics URL: {{error}}",
"configure": "Configure",
"error-loading": "Error loading checkers: {{error}}",
"table": {
"checker": "Checker",
"status": "Status",
"last-run": "Last Run",
"schedule": "Schedule",
"actions": "Actions"
},
"schedule": {
"enabled": "Enabled",
"disabled": "Disabled"
}
},
"other-checkers": {
"title": "Other available checkers",
"description": "These checkers are not directly associated with this domain but can be configured with domain-specific options."
},
"children-checkers": {
"title": "Zone & service checkers",
"description": "These checkers apply to zones or individual services. You can configure them here, but results will only appear when running checks at the appropriate scope."
},
"schedule": {
"card-title": "Automatic scheduling",
"interval-label": "Check interval",
"minutes": "minutes",
"hours": "hours",
"interval-hint": "Between {{intervalMin}} and {{intervalMax}}. Default: {{intervalDefault}}. The check will run once per interval.",
"no-schedule-yet": "No schedule created yet. Save to create one.",
"save": "Save",
"save-failed": "Failed to save schedule",
"saved": "Schedule saved successfully."
},
"executions": {
"loading": "Loading check results...",
"no-results": "No check results yet. Click \"Run Check Now\" to execute the check.",
"title": "Check Executions ({{count}})",
"run-check-now": "Run Check Now",
"delete-all": "Delete All",
"delete-all-confirm": "Are you sure you want to delete ALL check results for this checker? This cannot be undone.",
"deleted-all": "All check results have been deleted.",
"configure": "Configure",
"error-loading": "Error loading checker results: {{error}}",
"error-deleting": "Error deleting execution: {{error}}",
"table": {
"executed-at": "Executed At",
"status": "Status",
"duration": "Duration",
"actions": "Actions"
},
"view": "View"
},
"execution": {
"title": "Check Execution Details",
"field": {
"ended-at": "Ended At:",
"trigger": "Trigger:"
},
"status": {
"pending": "Pending",
"running": "Running",
"done": "Done",
"failed": "Failed",
"rate-limited": "Rate Limited",
"unknown": "Unknown"
}
},
"result": {
"loading": "Loading check result...",
"relaunch": "Relaunch Check",
"relaunch-failed": "Failed to relaunch check",
"error-loading": "Error loading check: {{error}}",
"type": {
"scheduled": "Scheduled Check",
"manual": "Manual Check"
},
"full-report": "Full Report",
"field": {
"executed-at": "Executed At:",
"duration": "Duration:",
"status": "Status:",
"status-message": "Message:",
"error": "Error:",
"rule": "Rule",
"message": "Message"
},
"no-results": "No results available for this execution.",
"view-metrics": "Metrics",
"view-html": "HTML Report",
"view-json": "Raw JSON",
"download-html": "Download HTML",
"download-json": "Download JSON",
"metric-name": "Metric",
"metric-value": "Value",
"metric-unit": "Unit"
},
"title": "Checkers",
"description": "Configure automated checks for your domains",
"available-count": "Available: {{count}} checkers",
"search-placeholder": "Search checkers...",
"loading": "Loading checkers...",
"loading-info": "Loading checker information...",
"no-checkers": "No checkers available",
"service-checks": "Service Checks",
"view-all": "View all",
"no-checks": "No checks available",
"load-error": "Error loading checks",
"error-loading": "Error loading checkers: {{error}}",
"error-loading-checker": "Error loading checker: {{error}}",
"checker-info-not-found": "Error: Checker information not found",
"table": {
"name": "Checker Name",
"availability": "Availability",
"actions": "Actions",
"manage": "Manage"
},
"availability": {
"domain": "Domain",
"zone": "Zone",
"general": "General",
"domain-level": "Domain-level",
"zone-level": "Zone-level",
"service-level": "Service-level"
},
"detail": {
"checker-information": "Checker Information",
"name": "Name:",
"availability": "Availability:",
"loading-options": "Loading options...",
"check-rules": "Rules",
"admin-options": "Admin Options",
"configuration": "Configuration",
"save": "Save",
"no-configurable-options": "This checker has no configurable options.",
"error-loading-options": "Error loading options: {{error}}",
"orphaned-options": "Orphaned options detected: {{options}}",
"clean-up": "Clean Up",
"read-only": "Read-only",
"auto-fill": "Auto-filled fields"
},
"option-groups": {
"domain-settings": "Domain-specific Settings",
"service-settings": "Service-specific Settings",
"checker-parameters": "Checker Parameters"
},
"auto-fill": {
"domain_name": "auto-filled: domain name",
"subdomain": "auto-filled: subdomain",
"service_type": "auto-filled: service type",
"generic": "auto-filled: {{key}}"
},
"messages": {
"options-updated": "Checker options updated successfully",
"options-cleaned": "Orphaned options removed successfully",
"update-failed": "Failed to update options: {{error}}",
"clean-failed": "Failed to clean options: {{error}}"
}
},
"compliance": {
"title": "Records compliance",
"checking": "Checking…",
"learn-more": "Learn more",
"all-passed": "All checks passed.",
"dkim": {
"missing-selector": {
"title": "Missing selector",
"detail": "DKIM records must be published as <selector>._domainkey.<domain>."
},
"invalid-selector": {
"title": "Invalid selector \"{{selector}}\"",
"detail": "Selectors must contain only letters, digits, hyphens or underscores."
},
"parse-error": {
"title": "Could not parse the DKIM record",
"detail": "The TXT value does not look like a key=value DKIM record."
},
"invalid-version": {
"title": "Unsupported DKIM version \"{{version}}\"",
"detail": "Only \"DKIM1\" is defined by RFC 6376."
},
"missing-key": {
"title": "Missing public key (p=)",
"detail": "Every DKIM record must publish a key. Use an empty p= only to revoke a key."
},
"revoked-key": {
"title": "Empty key, this DKIM record is revoked",
"detail": "An empty p= tag tells verifiers to ignore this selector."
},
"invalid-base64": {
"title": "Public key is not valid base64",
"detail": "p= must contain a base64-encoded SubjectPublicKeyInfo."
},
"weak-rsa-key": {
"title": "RSA key too short",
"detail": "RFC 8301 forbids RSA keys shorter than 1024 bits."
},
"short-rsa-key": {
"title": "RSA key shorter than recommended",
"detail": "Use 2048-bit (or longer) RSA keys per RFC 8301 §3.2."
},
"unknown-key-type": {
"title": "Unknown key type \"{{type}}\"",
"detail": "RFC 6376 defines \"rsa\"; RFC 8463 adds \"ed25519\"."
},
"deprecated-hash": {
"title": "Deprecated hash algorithm \"{{hash}}\"",
"detail": "RFC 8301 forbids SHA-1 in DKIM signatures."
},
"unknown-hash": {
"title": "Unknown hash algorithm \"{{hash}}\"",
"detail": "Common values are \"sha256\" (and historically \"sha1\")."
},
"unknown-service-type": {
"title": "Unrecognised service type \"{{type}}\"",
"detail": "Common values are \"email\" or \"*\"."
},
"unknown-flag": {
"title": "Unknown flag \"{{flag}}\"",
"detail": "RFC 6376 defines only \"y\" (testing) and \"s\" (strict i= alignment)."
},
"testing-mode": {
"title": "Testing mode is enabled (t=y)",
"detail": "Verifiers may ignore signatures from this selector. Remove the y flag once deployed."
},
"deprecated-granularity": {
"title": "g= tag is deprecated",
"detail": "Granularity was removed in RFC 6376; modern verifiers ignore it."
}
},
"bimi": {
"wrong-owner-name": {
"title": "BIMI record is at the wrong owner name \"{{name}}\"",
"detail": "BIMI records must be published at <selector>._bimi.<domain>."
},
"missing-selector": {
"title": "Missing selector",
"detail": "BIMI records must be published as <selector>._bimi.<domain>. Use \"default\" unless you publish multiple logos."
},
"invalid-selector": {
"title": "Invalid selector \"{{selector}}\"",
"detail": "Selectors must contain only letters, digits, hyphens or underscores."
},
"invalid-version": {
"title": "Unsupported BIMI version \"{{version}}\"",
"detail": "Only \"BIMI1\" is defined by the current draft."
},
"missing-location": {
"title": "Missing logo URL (l=)",
"detail": "BIMI requires a logo URL pointing to an SVG Tiny PS file."
},
"location-not-https": {
"title": "Logo URL is not HTTPS",
"detail": "Mail clients only fetch BIMI logos over HTTPS."
},
"location-not-svg": {
"title": "Logo URL does not end in .svg",
"detail": "BIMI requires SVG Tiny Portable/Secure logos. The URL should reference a .svg file."
},
"authority-not-https": {
"title": "VMC URL is not HTTPS",
"detail": "The Verified Mark Certificate URL must use HTTPS."
},
"authority-not-pem": {
"title": "VMC URL does not end in .pem",
"detail": "The Verified Mark Certificate is usually published as a PEM file."
},
"evidence-not-https": {
"title": "Evidence URL is not HTTPS",
"detail": "The evidence document URL should use HTTPS."
},
"missing-vmc": {
"title": "No Verified Mark Certificate (a=)",
"detail": "Gmail and Yahoo require a VMC to display the BIMI logo."
},
"declination": {
"title": "Declination to participate in BIMI",
"detail": "This record explicitly tells receivers that the domain has chosen not to participate in BIMI."
},
"no-dmarc": {
"title": "No DMARC record published",
"detail": "BIMI requires a DMARC record with an enforcing policy (quarantine or reject)."
},
"weak-dmarc-policy": {
"title": "DMARC policy is too weak for BIMI",
"detail": "Mail clients only honour BIMI when DMARC is set to quarantine or reject."
}
},
"dmarc": {
"wrong-owner-name": {
"title": "DMARC record is not at _dmarc.{{name}}",
"detail": "DMARC records must be published at _dmarc.<domain>."
},
"parse-error": {
"title": "Could not parse the DMARC record",
"detail": "The TXT value does not look like a key=value DMARC record."
},
"missing-version": {
"title": "Missing v=DMARC1",
"detail": "A DMARC record must start with the version tag v=DMARC1."
},
"invalid-version": {
"title": "Unsupported DMARC version \"{{version}}\"",
"detail": "Only \"DMARC1\" is defined by RFC 7489."
},
"missing-policy": {
"title": "Missing policy (p=)",
"detail": "DMARC requires a policy: none, quarantine or reject."
},
"invalid-policy": {
"title": "Unknown policy \"{{policy}}\"",
"detail": "p= must be one of: none, quarantine, reject."
},
"invalid-sp": {
"title": "Unknown subdomain policy \"{{policy}}\"",
"detail": "sp= must be one of: none, quarantine, reject."
},
"monitoring-only": {
"title": "Policy is p=none (monitoring only)",
"detail": "Receivers will collect reports but will not act on failed messages. Move to quarantine or reject once you trust the reports."
},
"invalid-alignment": {
"title": "Invalid {{tag}}=\"{{value}}\"",
"detail": "Alignment tags must be \"r\" (relaxed) or \"s\" (strict)."
},
"invalid-pct": {
"title": "pct=\"{{pct}}\" is out of range",
"detail": "pct must be an integer between 0 and 100."
},
"partial-deployment": {
"title": "DMARC applied to {{pct}}% of mail",
"detail": "Only a fraction of failing messages will be subject to the DMARC policy. Use this during rollout, then remove pct= once you trust the policy."
},
"invalid-ri": {
"title": "ri=\"{{ri}}\" is invalid",
"detail": "ri must be a positive integer in seconds (default 86400)."
},
"invalid-fo": {
"title": "Unknown failure-reporting option \"{{value}}\"",
"detail": "fo= accepts 0, 1, d or s (or a colon-separated combination)."
},
"unknown-rf": {
"title": "Unknown report format \"{{value}}\"",
"detail": "Only afrf is defined by RFC 7489."
},
"empty-uri": {
"title": "Empty {{tag}} entry",
"detail": "Remove the empty value or replace it with a destination URI."
},
"invalid-uri-scheme": {
"title": "{{tag}} URI \"{{uri}}\" is not mailto/http",
"detail": "DMARC report URIs must use mailto: (recommended) or http(s):."
},
"invalid-mailto": {
"title": "Malformed mailto URI in {{tag}}: \"{{uri}}\"",
"detail": "Expected mailto:user@example.com (an optional !size suffix is allowed)."
},
"no-alignment-source": {
"title": "No DKIM or SPF record found in this zone",
"detail": "DMARC needs at least one aligned mechanism. Without a DKIM or SPF record, no message can pass DMARC."
},
"no-alignment-source-enforcing": {
"title": "p={{policy}} but no DKIM or SPF record in this zone",
"detail": "Every legitimate message will fail DMARC and be quarantined or rejected. Publish DKIM and/or SPF before enforcing."
},
"strict-dkim-no-record": {
"title": "adkim=s but no DKIM record in this zone",
"detail": "Strict DKIM alignment requires the d= signing domain to match exactly. With no DKIM published, only SPF alignment can succeed."
}
},
"mta_sts": {
"wrong-owner-name": {
"title": "MTA-STS record is not at _mta-sts.{{name}}",
"detail": "MTA-STS records must be published at _mta-sts.<domain>."
},
"parse-error": {
"title": "Could not parse the MTA-STS record",
"detail": "The TXT value does not look like a key=value MTA-STS record."
},
"missing-version": {
"title": "Missing v=STSv1",
"detail": "An MTA-STS TXT record must start with v=STSv1."
},
"invalid-version": {
"title": "Unsupported MTA-STS version \"{{version}}\"",
"detail": "Only \"STSv1\" is defined by RFC 8461."
},
"missing-id": {
"title": "Missing policy id (id=)",
"detail": "MTA-STS requires a policy identifier; bump it whenever the policy file changes."
},
"invalid-id": {
"title": "Invalid policy id \"{{id}}\"",
"detail": "id must be 1 to 32 alphanumeric characters per RFC 8461 sec. 3.1."
},
"policy-dns-error": {
"title": "Cannot resolve mta-sts host",
"detail": "DNS lookup for the mta-sts.<domain> hostname failed. Publish an A/AAAA record so the policy at {{url}} can be reached."
},
"policy-tls-error": {
"title": "TLS handshake failed for the policy host",
"detail": "{{error}}"
},
"policy-not-found": {
"title": "No policy file at {{url}}",
"detail": "RFC 8461 sec. 3.3: the policy MUST be served at this URL. Publish the file or remove the TXT record."
},
"policy-http-error": {
"title": "Policy fetch returned HTTP {{code}}",
"detail": "The policy host responded with a non-2xx status; receivers will treat the policy as missing."
},
"policy-redirect": {
"title": "Policy host attempted a redirect (HTTP {{code}})",
"detail": "RFC 8461 sec. 3.3 forbids redirects on the policy URL. Serve the file directly at {{url}}."
},
"policy-fetch-error": {
"title": "Could not fetch the policy",
"detail": "{{error}}"
},
"policy-too-large": {
"title": "Policy body is too large",
"detail": "The file at {{url}} exceeds the size cap (64 KiB). MTA-STS policies are very small; trim the file."
},
"policy-missing-version": {
"title": "Policy file is missing the version key",
"detail": "Add a 'version: STSv1' line at the top of {{url}}."
},
"policy-invalid-version": {
"title": "Policy version \"{{version}}\" is unknown",
"detail": "Only \"STSv1\" is defined by RFC 8461."
},
"policy-missing-mode": {
"title": "Policy file is missing the mode key",
"detail": "Add a 'mode: enforce' (or testing / none) line in {{url}}."
},
"policy-invalid-mode": {
"title": "Policy mode \"{{mode}}\" is unknown",
"detail": "Mode must be one of: enforce, testing, none."
},
"policy-mode-none": {
"title": "Policy mode is \"none\" (MTA-STS effectively disabled)",
"detail": "Receivers will treat this as if no policy were published. Switch to enforce once you trust the policy."
},
"policy-mode-testing": {
"title": "Policy mode is \"testing\"",
"detail": "Receivers will report failures but still deliver. Switch to enforce once reports are clean."
},
"policy-missing-mx": {
"title": "Policy is missing mx entries",
"detail": "A {{mode}} policy must list at least one mx pattern; otherwise no mail can be delivered."
},
"policy-missing-max-age": {
"title": "Policy file is missing max_age",
"detail": "Add a 'max_age: <seconds>' line. Common values are 86400 (1 day) to 604800 (1 week) during rollout, then larger."
},
"policy-invalid-max-age": {
"title": "Policy max_age \"{{maxAge}}\" is out of range",
"detail": "max_age must be between 0 and 31557600 seconds (1 year)."
},
"policy-short-max-age": {
"title": "Policy max_age is short ({{maxAge}}s)",
"detail": "RFC 8461 recommends at least one week. Short values defeat caching and force receivers to refetch often."
}
},
"mx": {
"null-mx-with-others": {
"title": "Null MX cannot coexist with other MX records",
"detail": "RFC 7505 requires that a null MX (target \".\") be the only MX record in the set."
},
"null-mx-non-zero-preference": {
"title": "Null MX preference should be 0 (got {{preference}})",
"detail": "RFC 7505 specifies preference 0 for the null MX record."
},
"invalid-target": {
"title": "Invalid MX target \"{{target}}\"",
"detail": "MX targets must be valid hostnames per RFC 1035."
},
"invalid-preference": {
"title": "MX preference \"{{preference}}\" is out of range",
"detail": "MX preference must be a 16-bit unsigned integer (0..65535)."
},
"duplicate-target": {
"title": "Duplicate MX target \"{{target}}\"",
"detail": "The same target appears more than once. Keep only one record."
},
"target-is-cname": {
"title": "MX target \"{{target}}\" is a CNAME",
"detail": "RFC 5321 sec. 5.1 forbids MX records from pointing to a CNAME."
},
"target-no-address": {
"title": "MX target \"{{target}}\" has no A/AAAA in this zone",
"detail": "Add a Server entry for this name, or check that the target FQDN is correct."
}
},
"tlsrpt": {
"wrong-owner-name": {
"title": "TLS-RPT record is not at _smtp._tls.{{name}}",
"detail": "TLS-RPT records must be published at _smtp._tls.<domain>."
},
"parse-error": {
"title": "Could not parse the TLS-RPT record",
"detail": "The TXT value does not look like a key=value TLS-RPT record."
},
"missing-version": {
"title": "Missing v=TLSRPTv1",
"detail": "A TLS-RPT TXT record must start with v=TLSRPTv1."
},
"invalid-version": {
"title": "Unsupported TLS-RPT version \"{{version}}\"",
"detail": "Only \"TLSRPTv1\" is defined by RFC 8460."
},
"missing-rua": {
"title": "Missing rua= report destination",
"detail": "TLS-RPT requires at least one rua URI to receive aggregate reports."
},
"empty-rua": {
"title": "Empty rua entry",
"detail": "Remove the empty value or replace it with a destination URI."
},
"invalid-rua-scheme": {
"title": "rua URI \"{{uri}}\" is not mailto/http",
"detail": "TLS-RPT report URIs must use mailto: or http(s):."
},
"invalid-mailto": {
"title": "Malformed mailto URI in rua: \"{{uri}}\"",
"detail": "Expected mailto:user@example.com."
}
},
"spf": {
"missing-version": {
"title": "Missing v=spf1 prefix",
"detail": "An SPF record must start with the version tag v=spf1."
},
"wrong-version": {
"title": "Unsupported SPF version: {{version}}",
"detail": "Only v=spf1 is defined. Other versions are unsupported and will be ignored by receivers."
},
"no-all-mechanism": {
"title": "No 'all' mechanism nor redirect",
"detail": "Without a terminating 'all' mechanism (or a redirect modifier), receivers fall back to a neutral result for unknown senders. Add e.g. -all or ~all at the end."
},
"multiple-all": {
"title": "Multiple 'all' mechanisms ({{count}})",
"detail": "Only one 'all' mechanism is allowed; subsequent ones are ignored."
},
"all-not-last": {
"title": "'all' mechanism is not the last term",
"detail": "Mechanisms after 'all' are unreachable. Move 'all' to the end of the record."
},
"redirect-with-all": {
"title": "redirect= modifier combined with an 'all' mechanism",
"detail": "When 'all' is present, the redirect modifier is ignored. Remove one of them."
},
"multiple-redirect": {
"title": "Multiple redirect= modifiers",
"detail": "Only one redirect modifier is allowed per SPF record."
},
"ptr-deprecated": {
"title": "ptr mechanism is deprecated",
"detail": "The 'ptr' mechanism is slow and deprecated by RFC 7208. Use ip4/ip6 or include instead."
},
"too-many-lookups": {
"title": "More than {{max}} DNS lookups ({{count}})",
"detail": "RFC 7208 sec. 4.6.4: an SPF record must not require more than 10 DNS lookups. Counting include, a, mx, exists, ptr and redirect locally, this record already exceeds that budget."
},
"many-lookups": {
"title": "Approaching the SPF lookup limit ({{count}}/{{max}})",
"detail": "Counting include, a, mx, exists, ptr and redirect locally; recursion may push you above the 10-lookup hard limit."
},
"mechanism-missing-value": {
"title": "Mechanism '{{mechanism}}' requires a value",
"detail": "include, exists and redirect must be followed by a domain name (e.g. include:_spf.example.com)."
},
"duplicate-mechanism": {
"title": "Duplicate term: {{mechanism}}",
"detail": "Repeating the same mechanism has no effect and bloats the record."
},
"empty-term": {
"title": "Empty SPF term",
"detail": "Remove blank entries; a stray space produces an empty directive."
},
"unknown-mechanism": {
"title": "Unknown SPF mechanism '{{mechanism}}'",
"detail": "RFC 7208 sec. 5 defines all, include, a, mx, ptr, ip4, ip6 and exists. Anything else is treated as a permerror by verifiers."
},
"unknown-modifier": {
"title": "Unknown SPF modifier '{{modifier}}='",
"detail": "Only redirect= and exp= are defined by the SPF RFCs. Verifiers ignore unknown modifiers, but this is usually a typo."
},
"length-exceeds-txt-string": {
"title": "Record length is {{length}} characters",
"detail": "A single TXT string is capped at 255 characters; longer records must be split into multiple strings within the same RR."
},
"recursive-too-many-lookups": {
"title": "Recursive SPF walk exceeds the {{max}}-lookup limit ({{count}})",
"detail": "After resolving every include and redirect, this record needs more than 10 DNS lookups. Receivers will return PermError instead of evaluating it."
},
"recursive-many-lookups": {
"title": "Recursive SPF walk uses {{count}}/{{max}} lookups",
"detail": "You are within the budget but close to the limit. Adding another include or expanding an existing one is likely to push you over."
},
"too-many-void-lookups": {
"title": "More than {{max}} void DNS lookups ({{count}})",
"detail": "RFC 7208 §4.6.4 forbids more than two NXDOMAIN/NoData responses while evaluating SPF; receivers will return PermError."
},
"include-loop": {
"title": "SPF include loop on {{domain}}",
"detail": "An include or redirect points back to a domain already evaluated in the chain. Break the cycle."
},
"include-no-spf": {
"title": "No SPF record at {{domain}}",
"detail": "The mechanism {{mechanism}} resolves to a domain that does not publish v=spf1. The lookup still counts against the budget."
},
"include-resolver-error": {
"title": "Could not check {{domain}}",
"detail": "The resolver hit a transient error or a timeout while walking {{mechanism}}. Try again later."
},
"include-error": {
"title": "Issue resolving {{domain}}",
"detail": "The mechanism {{mechanism}} could not be fully evaluated."
}
}
}
}