Bläddra i källkod

Merge branch 'develop' into develop

jc21 1 månad sedan
förälder
incheckning
f649288098
49 ändrade filer med 3005 tillägg och 79 borttagningar
  1. 1 1
      .version
  2. 1 1
      README.md
  3. 9 1
      backend/certbot/dns-plugins.json
  4. 5 0
      backend/internal/nginx.js
  5. 50 0
      backend/migrations/20251111090000_redirect_auto_scheme.js
  6. 2 2
      backend/setup.js
  7. 1 1
      backend/templates/_access.conf
  8. 1 1
      docker/ci.env
  9. 12 2
      docker/docker-compose.ci.postgres.yml
  10. 39 40
      docker/docker-compose.ci.yml
  11. 5 3
      docker/docker-compose.dev.yml
  12. 2 1
      frontend/check-locales.cjs
  13. 1 1
      frontend/src/components/SiteMenu.tsx
  14. 29 15
      frontend/src/locale/IntlProvider.tsx
  15. 216 0
      frontend/src/locale/lang/de.json
  16. 2 1
      frontend/src/locale/lang/en.json
  17. 216 0
      frontend/src/locale/lang/es.json
  18. 215 0
      frontend/src/locale/lang/ja.json
  19. 3 0
      frontend/src/locale/lang/lang-list.json
  20. 7 0
      frontend/src/locale/src/HelpDoc/de/AccessLists.md
  21. 32 0
      frontend/src/locale/src/HelpDoc/de/Certificates.md
  22. 10 0
      frontend/src/locale/src/HelpDoc/de/DeadHosts.md
  23. 7 0
      frontend/src/locale/src/HelpDoc/de/ProxyHosts.md
  24. 7 0
      frontend/src/locale/src/HelpDoc/de/RedirectionHosts.md
  25. 6 0
      frontend/src/locale/src/HelpDoc/de/Streams.md
  26. 6 0
      frontend/src/locale/src/HelpDoc/de/index.ts
  27. 7 0
      frontend/src/locale/src/HelpDoc/es/AccessLists.md
  28. 32 0
      frontend/src/locale/src/HelpDoc/es/Certificates.md
  29. 10 0
      frontend/src/locale/src/HelpDoc/es/DeadHosts.md
  30. 7 0
      frontend/src/locale/src/HelpDoc/es/ProxyHosts.md
  31. 7 0
      frontend/src/locale/src/HelpDoc/es/RedirectionHosts.md
  32. 6 0
      frontend/src/locale/src/HelpDoc/es/Streams.md
  33. 6 0
      frontend/src/locale/src/HelpDoc/es/index.ts
  34. 11 5
      frontend/src/locale/src/HelpDoc/index.ts
  35. 8 0
      frontend/src/locale/src/HelpDoc/ja/AccessLists.md
  36. 21 0
      frontend/src/locale/src/HelpDoc/ja/Certificates.md
  37. 7 0
      frontend/src/locale/src/HelpDoc/ja/DeadHosts.md
  38. 7 0
      frontend/src/locale/src/HelpDoc/ja/ProxyHosts.md
  39. 5 0
      frontend/src/locale/src/HelpDoc/ja/RedirectionHosts.md
  40. 5 0
      frontend/src/locale/src/HelpDoc/ja/Streams.md
  41. 6 0
      frontend/src/locale/src/HelpDoc/ja/index.ts
  42. 644 0
      frontend/src/locale/src/de.json
  43. 4 1
      frontend/src/locale/src/en.json
  44. 644 0
      frontend/src/locale/src/es.json
  45. 641 0
      frontend/src/locale/src/ja.json
  46. 9 0
      frontend/src/locale/src/lang-list.json
  47. 1 1
      frontend/src/modals/CustomCertificateModal.tsx
  48. 31 1
      frontend/src/modals/RedirectionHostModal.tsx
  49. 1 1
      frontend/src/modules/Validations.tsx

+ 1 - 1
.version

@@ -1 +1 @@
-2.13.1
+2.13.3

+ 1 - 1
README.md

@@ -1,7 +1,7 @@
 <p align="center">
 	<img src="https://nginxproxymanager.com/github.png">
 	<br><br>
-	<img src="https://img.shields.io/badge/version-2.13.1-green.svg?style=for-the-badge">
+	<img src="https://img.shields.io/badge/version-2.13.3-green.svg?style=for-the-badge">
 	<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
 		<img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge">
 	</a>

+ 9 - 1
backend/certbot/dns-plugins.json

@@ -370,7 +370,7 @@
 	"leaseweb": {
 		"name": "LeaseWeb",
 		"package_name": "certbot-dns-leaseweb",
-		"version": "~=1.0.1",
+		"version": "~=1.0.3",
 		"dependencies": "",
 		"credentials": "dns_leaseweb_api_token = 01234556789",
 		"full_plugin_name": "dns-leaseweb"
@@ -399,6 +399,14 @@
 		"credentials": "dns_luadns_email = [email protected]\ndns_luadns_token = 0123456789abcdef0123456789abcdef",
 		"full_plugin_name": "dns-luadns"
 	},
+	"mchost24": {
+		"name": "MC-HOST24",
+		"package_name": "certbot-dns-mchost24",
+		"version": "",
+		"dependencies": "",
+		"credentials": "# Obtain API token using https://github.com/JoeJoeTV/mchost24-api-python\ndns_mchost24_api_token=<insert obtained API token here>",
+		"full_plugin_name": "dns-mchost24"
+	},
 	"mijnhost": {
 		"name": "mijn.host",
 		"package_name": "certbot-dns-mijn-host",

+ 5 - 0
backend/internal/nginx.js

@@ -216,6 +216,11 @@ const internalNginx = {
 				}
 			}
 
+			// For redirection hosts, if the scheme is not http or https, set it to $scheme
+			if (nice_host_type === "redirection_host" && ['http', 'https'].indexOf(host.forward_scheme.toLowerCase()) === -1) {
+				host.forward_scheme = "$scheme";
+			}
+
 			if (host.locations) {
 				//logger.info ('host.locations = ' + JSON.stringify(host.locations, null, 2));
 				origLocations = [].concat(host.locations);

+ 50 - 0
backend/migrations/20251111090000_redirect_auto_scheme.js

@@ -0,0 +1,50 @@
+import { migrate as logger } from "../logger.js";
+
+const migrateName = "redirect_auto_scheme";
+
+/**
+ * Migrate
+ *
+ * @see http://knexjs.org/#Schema
+ *
+ * @param   {Object} knex
+ * @returns {Promise}
+ */
+const up = (knex) => {
+	logger.info(`[${migrateName}] Migrating Up...`);
+
+	return knex.schema
+		.table("redirection_host", async (table) => {
+			// change the column default from $scheme to auto
+			await table.string("forward_scheme").notNull().defaultTo("auto").alter();
+			await knex('redirection_host')
+				.where('forward_scheme', '$scheme')
+				.update({ forward_scheme: 'auto' });
+		})
+		.then(() => {
+			logger.info(`[${migrateName}] redirection_host Table altered`);
+		});
+};
+
+/**
+ * Undo Migrate
+ *
+ * @param   {Object} knex
+ * @returns {Promise}
+ */
+const down = (knex) => {
+	logger.info(`[${migrateName}] Migrating Down...`);
+
+	return knex.schema
+		.table("redirection_host", async (table) => {
+			await table.string("forward_scheme").notNull().defaultTo("$scheme").alter();
+			await knex('redirection_host')
+				.where('forward_scheme', 'auto')
+				.update({ forward_scheme: '$scheme' });
+		})
+		.then(() => {
+			logger.info(`[${migrateName}] redirection_host Table altered`);
+		});
+};
+
+export { up, down };

+ 2 - 2
backend/setup.js

@@ -37,7 +37,7 @@ const setupDefaultUser = async () => {
 
 		const data = {
 			is_deleted: 0,
-			email: email,
+			email: initialAdminEmail,
 			name: "Administrator",
 			nickname: "Admin",
 			avatar: "",
@@ -53,7 +53,7 @@ const setupDefaultUser = async () => {
 			.insert({
 				user_id: user.id,
 				type: "password",
-				secret: password,
+				secret: initialAdminPassword,
 				meta: {},
 			});
 

+ 1 - 1
backend/templates/_access.conf

@@ -4,7 +4,7 @@
     auth_basic            "Authorization required";
     auth_basic_user_file  /data/access/{{ access_list_id }};
 
-    {% if access_list.pass_auth == 0 or access_list.pass_auth == true %}
+    {% if access_list.pass_auth == 0 or access_list.pass_auth == false %}
     proxy_set_header Authorization "";
     {% endif %}
 

+ 1 - 1
docker/ci.env

@@ -1,6 +1,6 @@
 AUTHENTIK_SECRET_KEY=gl8woZe8L6IIX8SC0c5Ocsj0xPkX5uJo5DVZCFl+L/QGbzuplfutYuua2ODNLEiDD3aFd9H2ylJmrke0
 AUTHENTIK_REDIS__HOST=authentik-redis
-AUTHENTIK_POSTGRESQL__HOST=db-postgres
+AUTHENTIK_POSTGRESQL__HOST=pgdb.internal
 AUTHENTIK_POSTGRESQL__USER=authentik
 AUTHENTIK_POSTGRESQL__NAME=authentik
 AUTHENTIK_POSTGRESQL__PASSWORD=07EKS5NLI6Tpv68tbdvrxfvj

+ 12 - 2
docker/docker-compose.ci.postgres.yml

@@ -6,7 +6,7 @@ services:
 
   fullstack:
     environment:
-      DB_POSTGRES_HOST: "db-postgres"
+      DB_POSTGRES_HOST: "pgdb.internal"
       DB_POSTGRES_PORT: "5432"
       DB_POSTGRES_USER: "npm"
       DB_POSTGRES_PASSWORD: "npmpass"
@@ -27,7 +27,9 @@ services:
       - psql_vol:/var/lib/postgresql/data
       - ./ci/postgres:/docker-entrypoint-initdb.d
     networks:
-      - fulltest
+      fulltest:
+        aliases:
+          - pgdb.internal
 
   authentik-redis:
     image: "redis:alpine"
@@ -41,6 +43,8 @@ services:
       timeout: 3s
     volumes:
       - redis_vol:/data
+    networks:
+      - fulltest
 
   authentik:
     image: ghcr.io/goauthentik/server:2024.10.1
@@ -51,6 +55,8 @@ services:
     depends_on:
       - authentik-redis
       - db-postgres
+    networks:
+      - fulltest
 
   authentik-worker:
     image: ghcr.io/goauthentik/server:2024.10.1
@@ -61,6 +67,8 @@ services:
     depends_on:
       - authentik-redis
       - db-postgres
+    networks:
+      - fulltest
 
   authentik-ldap:
     image: ghcr.io/goauthentik/ldap:2024.10.1
@@ -71,6 +79,8 @@ services:
     restart: unless-stopped
     depends_on:
       - authentik
+    networks:
+      - fulltest
 
 volumes:
   psql_vol:

+ 39 - 40
docker/docker-compose.ci.yml

@@ -3,31 +3,30 @@
 # This is a base compose file, it should be extended with a
 # docker-compose.ci.*.yml file
 services:
-
   fullstack:
     image: "${IMAGE}:${BRANCH_LOWER}-ci-${BUILD_NUMBER}"
     environment:
       TZ: "${TZ:-Australia/Brisbane}"
-      DEBUG: 'true'
-      CI: 'true'
+      DEBUG: "true"
+      CI: "true"
       FORCE_COLOR: 1
       # Required for DNS Certificate provisioning in CI
-      LE_SERVER: 'https://ca.internal/acme/acme/directory'
-      REQUESTS_CA_BUNDLE: '/etc/ssl/certs/NginxProxyManager.crt'
+      LE_SERVER: "https://ca.internal/acme/acme/directory"
+      REQUESTS_CA_BUNDLE: "/etc/ssl/certs/NginxProxyManager.crt"
     volumes:
-      - 'npm_data_ci:/data'
-      - 'npm_le_ci:/etc/letsencrypt'
-      - './dev/letsencrypt.ini:/etc/letsencrypt.ini:ro'
-      - './dev/resolv.conf:/etc/resolv.conf:ro'
-      - '/etc/localtime:/etc/localtime:ro'
+      - "npm_data_ci:/data"
+      - "npm_le_ci:/etc/letsencrypt"
+      - "./dev/letsencrypt.ini:/etc/letsencrypt.ini:ro"
+      - "./dev/resolv.conf:/etc/resolv.conf:ro"
+      - "/etc/localtime:/etc/localtime:ro"
     healthcheck:
       test: ["CMD", "/usr/bin/check-health"]
       interval: 10s
       timeout: 3s
     expose:
-      - '80-81/tcp'
-      - '443/tcp'
-      - '1500-1503/tcp'
+      - "80-81/tcp"
+      - "443/tcp"
+      - "1500-1503/tcp"
     networks:
       fulltest:
         aliases:
@@ -38,8 +37,8 @@ services:
   stepca:
     image: jc21/testca
     volumes:
-      - './dev/resolv.conf:/etc/resolv.conf:ro'
-      - '/etc/localtime:/etc/localtime:ro'
+      - "./dev/resolv.conf:/etc/resolv.conf:ro"
+      - "/etc/localtime:/etc/localtime:ro"
     networks:
       fulltest:
         aliases:
@@ -48,18 +47,18 @@ services:
   pdns:
     image: pschiffe/pdns-mysql:4.8
     volumes:
-      - '/etc/localtime:/etc/localtime:ro'
+      - "/etc/localtime:/etc/localtime:ro"
     environment:
-      PDNS_master: 'yes'
-      PDNS_api: 'yes'
-      PDNS_api_key: 'npm'
-      PDNS_webserver: 'yes'
-      PDNS_webserver_address: '0.0.0.0'
-      PDNS_webserver_password: 'npm'
-      PDNS_webserver-allow-from: '127.0.0.0/8,192.0.0.0/8,10.0.0.0/8,172.0.0.0/8'
-      PDNS_version_string: 'anonymous'
+      PDNS_master: "yes"
+      PDNS_api: "yes"
+      PDNS_api_key: "npm"
+      PDNS_webserver: "yes"
+      PDNS_webserver_address: "0.0.0.0"
+      PDNS_webserver_password: "npm"
+      PDNS_webserver-allow-from: "127.0.0.0/8,192.0.0.0/8,10.0.0.0/8,172.0.0.0/8"
+      PDNS_version_string: "anonymous"
       PDNS_default_ttl: 1500
-      PDNS_allow_axfr_ips: '127.0.0.0/8,192.0.0.0/8,10.0.0.0/8,172.0.0.0/8'
+      PDNS_allow_axfr_ips: "127.0.0.0/8,192.0.0.0/8,10.0.0.0/8,172.0.0.0/8"
       PDNS_gmysql_host: pdns-db
       PDNS_gmysql_port: 3306
       PDNS_gmysql_user: pdns
@@ -76,14 +75,14 @@ services:
   pdns-db:
     image: mariadb
     environment:
-      MYSQL_ROOT_PASSWORD: 'pdns'
-      MYSQL_DATABASE: 'pdns'
-      MYSQL_USER: 'pdns'
-      MYSQL_PASSWORD: 'pdns'
+      MYSQL_ROOT_PASSWORD: "pdns"
+      MYSQL_DATABASE: "pdns"
+      MYSQL_USER: "pdns"
+      MYSQL_PASSWORD: "pdns"
     volumes:
-      - 'pdns_mysql_vol:/var/lib/mysql'
-      - '/etc/localtime:/etc/localtime:ro'
-      - './dev/pdns-db.sql:/docker-entrypoint-initdb.d/01_init.sql:ro'
+      - "pdns_mysql_vol:/var/lib/mysql"
+      - "/etc/localtime:/etc/localtime:ro"
+      - "./dev/pdns-db.sql:/docker-entrypoint-initdb.d/01_init.sql:ro"
     networks:
       - fulltest
 
@@ -100,12 +99,12 @@ services:
       context: ../
       dockerfile: test/cypress/Dockerfile
     environment:
-      HTTP_PROXY: 'squid:3128'
-      HTTPS_PROXY: 'squid:3128'
+      HTTP_PROXY: "squid:3128"
+      HTTPS_PROXY: "squid:3128"
     volumes:
-      - 'cypress_logs:/test/results'
-      - './dev/resolv.conf:/etc/resolv.conf:ro'
-      - '/etc/localtime:/etc/localtime:ro'
+      - "cypress_logs:/test/results"
+      - "./dev/resolv.conf:/etc/resolv.conf:ro"
+      - "/etc/localtime:/etc/localtime:ro"
     command: cypress run --browser chrome --config-file=cypress/config/ci.js
     networks:
       - fulltest
@@ -113,9 +112,9 @@ services:
   squid:
     image: ubuntu/squid
     volumes:
-      - './dev/squid.conf:/etc/squid/squid.conf:ro'
-      - './dev/resolv.conf:/etc/resolv.conf:ro'
-      - '/etc/localtime:/etc/localtime:ro'
+      - "./dev/squid.conf:/etc/squid/squid.conf:ro"
+      - "./dev/resolv.conf:/etc/resolv.conf:ro"
+      - "/etc/localtime:/etc/localtime:ro"
     networks:
       - fulltest
 

+ 5 - 3
docker/docker-compose.dev.yml

@@ -32,7 +32,7 @@ services:
       # DB_MYSQL_PASSWORD: 'npm'
       # DB_MYSQL_NAME: 'npm'
       # db-postgres:
-      DB_POSTGRES_HOST: "db-postgres"
+      DB_POSTGRES_HOST: "pgdb.internal"
       DB_POSTGRES_PORT: "5432"
       DB_POSTGRES_USER: "npm"
       DB_POSTGRES_PASSWORD: "npmpass"
@@ -81,8 +81,6 @@ services:
   db-postgres:
     image: postgres:17
     container_name: npm2dev.db-postgres
-    networks:
-      - nginx_proxy_manager
     environment:
       POSTGRES_USER: "npm"
       POSTGRES_PASSWORD: "npmpass"
@@ -90,6 +88,10 @@ services:
     volumes:
       - psql_data:/var/lib/postgresql/data
       - ./ci/postgres:/docker-entrypoint-initdb.d
+    networks:
+      nginx_proxy_manager:
+        aliases:
+          - pgdb.internal
 
   stepca:
     image: jc21/testca

+ 2 - 1
frontend/check-locales.cjs

@@ -8,7 +8,8 @@
 
 const allLocales = [
 	["en", "en-US"],
-	["fa", "fa-IR"],
+	["es", "es-ES"],
+	["de", "de-DE"],
 ];
 
 const ignoreUnused = [

+ 1 - 1
frontend/src/components/SiteMenu.tsx

@@ -190,7 +190,7 @@ export function SiteMenu() {
 
 	return (
 		<header className="navbar-expand-md">
-			<div className="collapse navbar-collapse">
+			<div className="collapse navbar-collapse"  id="navbar-menu">
 				<div className="navbar">
 					<div className="container-xl">
 						<div className="row flex-column flex-md-row flex-fill align-items-center">

+ 29 - 15
frontend/src/locale/IntlProvider.tsx

@@ -1,18 +1,33 @@
 import { createIntl, createIntlCache } from "react-intl";
 import langEn from "./lang/en.json";
+import langDe from "./lang/de.json";
+import langEs from "./lang/es.json";
+import langJa from "./lang/ja.json";
 import langRu from "./lang/ru.json";
 import langList from "./lang/lang-list.json";
 
 // first item of each array should be the language code,
 // not the country code
 // Remember when adding to this list, also update check-locales.js script
-const localeOptions = [["en", "en-US"], ["ru", "ru-RU"]];
+const localeOptions = [
+	["en", "en-US"],
+	["de", "de-DE"],
+	["es", "es-ES"],
+	["ja", "ja-JP"],
+	["ru", "ru-RU"],
+];
 
 const loadMessages = (locale?: string): typeof langList & typeof langEn => {
 	const thisLocale = locale || "en";
 	switch (thisLocale.slice(0, 2)) {
+		case "de":
+			return Object.assign({}, langList, langEn, langDe);
+		case "es":
+			return Object.assign({}, langList, langEn, langEs);
+		case "ja":
+			return Object.assign({}, langList, langEn, langJa);
 		case "ru":
-			return Object.assign({}, langList, langRu);
+			return Object.assign({}, langList, langEn, langRu);
 		default:
 			return Object.assign({}, langList, langEn);
 	}
@@ -20,6 +35,16 @@ const loadMessages = (locale?: string): typeof langList & typeof langEn => {
 
 const getFlagCodeForLocale = (locale?: string) => {
 	switch (locale) {
+		case "es-ES":
+		case "es":
+			return "ES";
+		case "de-DE":
+		case "de":
+			return "DE";
+		case "ja-JP":
+		case "ja":
+			return "JP";
+		case "ru-RU":
 		case "ru":
 			return "RU";
 		default:
@@ -45,10 +70,7 @@ const getLocale = (short = false) => {
 const cache = createIntlCache();
 
 const initialMessages = loadMessages(getLocale());
-let intl = createIntl(
-	{ locale: getLocale(), messages: initialMessages },
-	cache,
-);
+let intl = createIntl({ locale: getLocale(), messages: initialMessages }, cache);
 
 const changeLocale = (locale: string): void => {
 	const messages = loadMessages(locale);
@@ -88,12 +110,4 @@ const T = ({
 	);
 };
 
-export {
-	localeOptions,
-	getFlagCodeForLocale,
-	getLocale,
-	createIntl,
-	changeLocale,
-	intl,
-	T,
-};
+export { localeOptions, getFlagCodeForLocale, getLocale, createIntl, changeLocale, intl, T };

+ 216 - 0
frontend/src/locale/lang/de.json

@@ -0,0 +1,216 @@
+{
+  "access-list": "Zugriffsliste",
+  "access-list.access-count": "{count} {count, plural, one {Regel} other {Regeln}}",
+  "access-list.auth-count": "{count} {count, plural, one {User} other {Users}}",
+  "access-list.help-rules-last": "Wenn mindestens eine Regel vorhanden ist, wird diese Regel zum Ablehnen aller Anfragen als letzte hinzugefügt.",
+  "access-list.help.rules-order": "Beachten Sie, dass die Anweisungen „Erlauben“ und „Verbieten“ in der Reihenfolge ihrer Definition angewendet werden.",
+  "access-list.pass-auth": "Authentifizierung an Upstream weiterleiten",
+  "access-list.public": "Öffentlich",
+  "access-list.public.subtitle": "Keine Authentifizierung erforderlich",
+  "access-list.satisfy-any": "Satisfy Any",
+  "access-list.subtitle": "{users} {users, plural, one {User} other {Users}}, {rules} {rules, plural, one {Regel} other {Regeln}} - Erstellt: {date}",
+  "access-lists": "Zugrifflisten",
+  "action.add": "Hinzufügen",
+  "action.add-location": "Pfad Hinzufügen",
+  "action.close": "Schließen",
+  "action.delete": "Löschen",
+  "action.disable": "Deaktivieren",
+  "action.download": "Herunterladen",
+  "action.edit": "Bearbeiten",
+  "action.enable": "Aktivieren",
+  "action.permissions": "Berechtigungen",
+  "action.renew": "Erneuert",
+  "action.view-details": "Details",
+  "auditlogs": "Protokoll",
+  "cancel": "Abbrechen",
+  "certificate": "Zertifikat",
+  "certificate.custom-certificate": "Zertifikat",
+  "certificate.custom-certificate-key": "Privater Schlüssel",
+  "certificate.custom-intermediate": "Zwischen Zertifikat",
+  "certificate.in-use": "In Benutzung",
+  "certificate.none.subtitle": "Kein Zertifikat zugewiesen",
+  "certificate.none.subtitle.for-http": "Dieser Host verwendet kein HTTPS.",
+  "certificate.none.title": "Kein",
+  "certificate.not-in-use": "Nicht in Benutzung",
+  "certificate.renew": "Zertifikat erneuern",
+  "certificates": "Zertifikate",
+  "certificates.custom": "Benutzerdefiniertes Zertifikat",
+  "certificates.custom.warning": "Mit einem Passwort geschützte Schlüsseldateien werden nicht unterstützt.",
+  "certificates.dns.credentials": "Inhalt der Anmeldedaten-Datei",
+  "certificates.dns.credentials-note": "Dieses Plugin erfordert eine Konfigurationsdatei, die einen API-Token oder andere Anmeldedaten für Ihren Anbieter enthält.",
+  "certificates.dns.credentials-warning": "Diese Daten werden als Klartext in der Datenbank und in einer Datei gespeichert!",
+  "certificates.dns.propagation-seconds": "Wartzeit in Sekunden",
+  "certificates.dns.propagation-seconds-note": "Leer lassen um die Standardwartezeit des Plugins zu nutzen",
+  "certificates.dns.provider": "DNS Provider",
+  "certificates.dns.warning": "Dieser Abschnitt erfordert einige Kenntnisse über Certbot und seine DNS-Plugins. Bitte konsultieren Sie die jeweilige Plugin-Dokumentation.",
+  "certificates.http.reachability-404": "Unter dieser Domain wurde ein Server gefunden, aber es scheint sich nicht um Nginx Proxy Manager zu handeln. Bitte stellen Sie sicher, dass Ihre Domain auf die IP-Adresse verweist, unter der Ihre NPM-Instanz ausgeführt wird.",
+  "certificates.http.reachability-failed-to-check": "Die Erreichbarkeit konnte aufgrund eines Kommunikationsfehlers mit site24x7.com nicht überprüft werden.",
+  "certificates.http.reachability-not-resolved": "Unter dieser Domain ist kein Server verfügbar. Bitte stellen Sie sicher, dass Ihre Domain existiert und auf die IP-Adresse verweist, unter der Ihre NPM-Instanz läuft, und dass gegebenenfalls Port 80 in Ihrem Router weitergeleitet wird.",
+  "certificates.http.reachability-ok": "Ihr Server ist erreichbar und die Erstellung von Zertifikaten sollte möglich sein.",
+  "certificates.http.reachability-other": "Unter dieser Domain wurde ein Server gefunden, der jedoch einen unerwarteten Statuscode {code} zurückgegeben hat. Handelt es sich um den NPM-Server? Bitte stellen Sie sicher, dass Ihre Domain auf die IP-Adresse verweist, unter der Ihre NPM-Instanz ausgeführt wird.",
+  "certificates.http.reachability-wrong-data": "Unter dieser Domain wurde ein Server gefunden, der jedoch unerwartete Daten zurückgegeben hat. Handelt es sich um den NPM-Server? Bitte stellen Sie sicher, dass Ihre Domain auf die IP-Adresse verweist, unter der Ihre NPM-Instanz ausgeführt wird.",
+  "certificates.http.test-results": "Test Ergeniss",
+  "certificates.http.warning": "Diese Domänen müssen bereits so konfiguriert sein, dass sie auf diese Installation verweisen.",
+  "certificates.request.subtitle": "Über Let's Encrypt",
+  "certificates.request.title": "Anfordern eines neuen Zertifikates",
+  "column.access": "Zugriff",
+  "column.authorization": "Genehmigung",
+  "column.authorizations": "Genehmigungen",
+  "column.custom-locations": "Benutzerdefinierte Pfad",
+  "column.destination": "Ziel",
+  "column.details": "Details",
+  "column.email": "Email",
+  "column.event": "Ereignis",
+  "column.expires": "Verfällt am",
+  "column.http-code": "HTTP Code",
+  "column.incoming-port": "Eingehender Port",
+  "column.name": "Name",
+  "column.protocol": "Protokoll",
+  "column.provider": "Provider",
+  "column.roles": "Rollen",
+  "column.rules": "Regeln",
+  "column.satisfy": "Satisfy",
+  "column.satisfy-all": "Alle",
+  "column.satisfy-any": "Jeder",
+  "column.scheme": "Schema",
+  "column.source": "Quelle",
+  "column.ssl": "SSL",
+  "column.status": "Status",
+  "created-on": "Erstelldatum: {date}",
+  "dashboard": "Dashboard",
+  "dead-host": "404 Host",
+  "dead-hosts": "404 Hosts",
+  "dead-hosts.count": "{count} {count, plural, one {404 Host} other {404 Hosts}}",
+  "disabled": "Deaktiviert",
+  "domain-names": "Domain Names",
+  "domain-names.max": "{count} Maximale Anzahl von Domainnamen",
+  "domain-names.placeholder": "Eintragen der Domain...",
+  "domain-names.wildcards-not-permitted": "Wildcards sind für diesen Typ nicht zulässig.",
+  "domain-names.wildcards-not-supported": "Wildcards werden für diese Zertifizierungsstelle nicht unterstützt.",
+  "domains.force-ssl": "Erzwinge SSL",
+  "domains.hsts-enabled": "HSTS aktiviert",
+  "domains.hsts-subdomains": "HSTS Sub-domains",
+  "domains.http2-support": "HTTP/2 Support",
+  "domains.use-dns": "Nutze DNS Challenge",
+  "email-address": "Email Addresse",
+  "empty-search": "Keine Ergebnisse gefunden",
+  "empty-subtitle": "Warum erstellen Sie nicht eine?",
+  "enabled": "aktiviert",
+  "error.access.at-least-one": "Entweder eine Genehmigung oder eine Zugriffsregel ist erforderlich.",
+  "error.access.duplicate-usernames": "Autorisierung Benutzernamen müssen eindeutig sein",
+  "error.invalid-auth": "Ungültige E-Mail-Adresse oder Passwort",
+  "error.invalid-domain": "Ungültige Domain: {domain}",
+  "error.invalid-email": "Ungültige E-Mail-Adresse",
+  "error.max-character-length": "Die maximale Länge beträgt {max} Zeichen{max, plural, one {} other {s}}",
+  "error.max-domains": "Zu viele Domains, maximal sind {max}",
+  "error.maximum": "Maximum ist {max}",
+  "error.min-character-length": "Die minimale Länge beträgt {min} Zeichen{min, plural, one {} other {s}}",
+  "error.minimum": "Minimum ist {min}",
+  "error.passwords-must-match": "Passwörter müssen übereinstimmen",
+  "error.required": "Dies ist erforderlich.",
+  "expires.on": "Ablauf am: {date}",
+  "footer.github-fork": "Fork me on Github",
+  "host.flags.block-exploits": "Gängige Exploits blockieren",
+  "host.flags.cache-assets": "Cache Assets",
+  "host.flags.preserve-path": "Pfad beibehalten",
+  "host.flags.protocols": "Protokole",
+  "host.flags.websockets-upgrade": "Websockets Support",
+  "host.forward-port": "Forward Port",
+  "host.forward-scheme": "Schema",
+  "hosts": "Hosts",
+  "http-only": "HTTP Only",
+  "lets-encrypt": "Let's Encrypt",
+  "lets-encrypt-via-dns": "Let's Encrypt via DNS",
+  "lets-encrypt-via-http": "Let's Encrypt via HTTP",
+  "loading": "Laden…",
+  "login.title": "Account Login",
+  "nginx-config.label": "Benutzerdefinierte Nginx Konfiguration",
+  "nginx-config.placeholder": "# Geben Sie hier Ihre benutzerdefinierte Nginx-Konfiguration auf eigene Gefahr ein!",
+  "no-permission-error": "Sie haben keinen Zugriff, um dies anzuzeigen.",
+  "notfound.action": "Take me home",
+  "notfound.content": "We are sorry but the page you are looking for was not found",
+  "notfound.title": "Oops… You just found an error page",
+  "notification.error": "Error",
+  "notification.object-deleted": "{object} wurde gelöscht",
+  "notification.object-disabled": "{object} wurde deaktiviert",
+  "notification.object-enabled": "{object} wurde aktiviert",
+  "notification.object-renewed": "{object} wurde erneuert",
+  "notification.object-saved": "{object} wurde gespeichert",
+  "notification.success": "Erfolgreich",
+  "object.actions-title": "{object} #{id}",
+  "object.add": "{object} hinzufügen",
+  "object.delete": "{object} löschen",
+  "object.delete.content": "Bist du dir sicher das du diese(n) {object} löschen möchtest?",
+  "object.edit": "{object} bearbeiten",
+  "object.empty": "Keine {objects} vorhanden",
+  "object.event.created": "{object} erstellt",
+  "object.event.deleted": "{object} gelöscht",
+  "object.event.disabled": "{object} deaktiviert",
+  "object.event.enabled": "{object} aktiviert",
+  "object.event.renewed": "{object} erneuert",
+  "object.event.updated": "{object} aktualisiert",
+  "offline": "Offline",
+  "online": "Online",
+  "options": "Optionen",
+  "password": "Passwort",
+  "password.generate": "Zufälliges Passwort generieren",
+  "password.hide": "Passwort verstecken",
+  "password.show": "Passwort anzeigen",
+  "permissions.hidden": "Versteckt",
+  "permissions.manage": "Verwalten",
+  "permissions.view": "Nur anzeigen",
+  "permissions.visibility.all": "Alle Elemente",
+  "permissions.visibility.title": "Objekt Sichtbarkeit",
+  "permissions.visibility.user": "Nur erstellte Elemente",
+  "proxy-host": "Proxy Host",
+  "proxy-host.forward-host": "Forward Hostname / IP",
+  "proxy-hosts": "Proxy Hosts",
+  "proxy-hosts.count": "{count} {count, plural, one {Proxy Host} other {Proxy Hosts}}",
+  "public": "Öffentlich",
+  "redirection-host": "Redirection Host",
+  "redirection-host.forward-domain": "Forward Domain",
+  "redirection-host.forward-http-code": "HTTP Code",
+  "redirection-hosts": "Redirection Hosts",
+  "redirection-hosts.count": "{count} {count, plural, one {Redirection Host} other {Redirection Hosts}}",
+  "role.admin": "Administrator",
+  "role.standard-user": "Standard User",
+  "save": "Speichern",
+  "setting": "Einstellung",
+  "settings": "Einstellungen",
+  "settings.default-site": "Standard Seite",
+  "settings.default-site.404": "404 Page",
+  "settings.default-site.444": "No Response (444)",
+  "settings.default-site.congratulations": "Willkommensseite",
+  "settings.default-site.description": "Was angezeigt wird, wenn der Nginx eine unbekannte Webseitenanfrage bekommt",
+  "settings.default-site.html": "Benutzerdefinierte HTML",
+  "settings.default-site.html.placeholder": "<!-- Geben Sie hier Ihren benutzerdefinierten HTML-Inhalt ein. -->",
+  "settings.default-site.redirect": "Weiterleitung",
+  "setup.preamble": "Beginnen Sie mit der Erstellung Ihres Administratorkontos.",
+  "setup.title": "Willkommen!",
+  "sign-in": "Login",
+  "ssl-certificate": "SSL Zertifikate",
+  "stream": "Stream",
+  "stream.forward-host": "Forward Host",
+  "stream.incoming-port": "Incoming Port",
+  "streams": "Streams",
+  "streams.count": "{count} {count, plural, one {Stream} other {Streams}}",
+  "streams.tcp": "TCP",
+  "streams.udp": "UDP",
+  "test": "Test",
+  "user": "User",
+  "user.change-password": "Passwort ändern",
+  "user.confirm-password": "Passwort wiederholen",
+  "user.current-password": "Aktuelles Passwort",
+  "user.edit-profile": "Profil bearbeiten",
+  "user.full-name": "Name",
+  "user.login-as": "Einloggen als {name}",
+  "user.logout": "Ausloggen",
+  "user.new-password": "Neues Password",
+  "user.nickname": "Nickname",
+  "user.set-password": "Passwort setzen",
+  "user.set-permissions": "Berechtigungen für {name} setzen",
+  "user.switch-dark": "Zum Dark Mode wechseln",
+  "user.switch-light": "Zum Light Mode wechslen",
+  "username": "Benutzername",
+  "users": "Benutzer"
+}

+ 2 - 1
frontend/src/locale/lang/en.json

@@ -62,7 +62,7 @@
   "column.email": "Email",
   "column.event": "Event",
   "column.expires": "Expires",
-  "column.http-code": "Access",
+  "column.http-code": "HTTP Code",
   "column.incoming-port": "Incoming Port",
   "column.name": "Name",
   "column.protocol": "Protocol",
@@ -169,6 +169,7 @@
   "public": "Public",
   "redirection-host": "Redirection Host",
   "redirection-host.forward-domain": "Forward Domain",
+  "redirection-host.forward-http-code": "HTTP Code",
   "redirection-hosts": "Redirection Hosts",
   "redirection-hosts.count": "{count} {count, plural, one {Redirection Host} other {Redirection Hosts}}",
   "role.admin": "Administrator",

+ 216 - 0
frontend/src/locale/lang/es.json

@@ -0,0 +1,216 @@
+{
+  "access-list": "Lista de Acceso",
+  "access-list.access-count": "{count} {count, plural, one {Regla} other {Reglas}}",
+  "access-list.auth-count": "{count} {count, plural, one {Usuario} other {Usuarios}}",
+  "access-list.help-rules-last": "Cuando exista al menos 1 regla, esta regla de denegar todo se añadirá al final",
+  "access-list.help.rules-order": "Ten en cuenta que las directivas de permitir y denegar se aplicarán en el orden en que estén definidas.",
+  "access-list.pass-auth": "Pasar Autenticación al Upstream",
+  "access-list.public": "Accesible Públicamente",
+  "access-list.public.subtitle": "No se requiere autenticación básica",
+  "access-list.satisfy-any": "Satisfacer Cualquiera",
+  "access-list.subtitle": "{users} {users, plural, one {Usuario} other {Usuarios}}, {rules} {rules, plural, one {Regla} other {Reglas}} - Creado: {date}",
+  "access-lists": "Listas de Acceso",
+  "action.add": "Añadir",
+  "action.add-location": "Añadir Ubicación",
+  "action.close": "Cerrar",
+  "action.delete": "Eliminar",
+  "action.disable": "Deshabilitar",
+  "action.download": "Descargar",
+  "action.edit": "Editar",
+  "action.enable": "Habilitar",
+  "action.permissions": "Permisos",
+  "action.renew": "Renovar",
+  "action.view-details": "Ver Detalles",
+  "auditlogs": "Registros de Auditoría",
+  "cancel": "Cancelar",
+  "certificate": "Certificado",
+  "certificate.custom-certificate": "Certificado",
+  "certificate.custom-certificate-key": "Clave del Certificado",
+  "certificate.custom-intermediate": "Certificado Intermedio",
+  "certificate.in-use": "En Uso",
+  "certificate.none.subtitle": "Sin certificado asignado",
+  "certificate.none.subtitle.for-http": "Este host no usará HTTPS",
+  "certificate.none.title": "Ninguno",
+  "certificate.not-in-use": "Sin Usar",
+  "certificate.renew": "Renovar Certificado",
+  "certificates": "Certificados",
+  "certificates.custom": "Certificado Personalizado",
+  "certificates.custom.warning": "No se admiten archivos de claves protegidos con contraseña.",
+  "certificates.dns.credentials": "Contenido del Archivo de Credenciales",
+  "certificates.dns.credentials-note": "Este plugin requiere un archivo de configuración que contenga un token de API u otras credenciales para tu proveedor",
+  "certificates.dns.credentials-warning": "¡Estos datos se almacenarán como texto plano en la base de datos y en un archivo!",
+  "certificates.dns.propagation-seconds": "Segundos de Propagación",
+  "certificates.dns.propagation-seconds-note": "Dejar vacío para usar el valor predeterminado del plugin. Número de segundos a esperar para la propagación DNS.",
+  "certificates.dns.provider": "Proveedor DNS",
+  "certificates.dns.warning": "Esta sección requiere algunos conocimientos sobre Certbot y sus plugins DNS. Consulta la documentación de los plugins respectivos.",
+  "certificates.http.reachability-404": "Se encontró un servidor en este dominio pero no parece ser Nginx Proxy Manager. Asegúrate de que tu dominio apunte a la IP donde se está ejecutando tu instancia de NPM.",
+  "certificates.http.reachability-failed-to-check": "No se pudo verificar la accesibilidad debido a un error de comunicación con site24x7.com.",
+  "certificates.http.reachability-not-resolved": "No hay ningún servidor disponible en este dominio. Asegúrate de que tu dominio existe y apunta a la IP donde se está ejecutando tu instancia de NPM y, si es necesario, que el puerto 80 esté redirigido en tu router.",
+  "certificates.http.reachability-ok": "Tu servidor es accesible y debería ser posible crear certificados.",
+  "certificates.http.reachability-other": "Se encontró un servidor en este dominio pero devolvió un código de estado inesperado {code}. ¿Es el servidor NPM? Asegúrate de que tu dominio apunte a la IP donde se está ejecutando tu instancia de NPM.",
+  "certificates.http.reachability-wrong-data": "Se encontró un servidor en este dominio pero devolvió datos inesperados. ¿Es el servidor NPM? Asegúrate de que tu dominio apunte a la IP donde se está ejecutando tu instancia de NPM.",
+  "certificates.http.test-results": "Resultados de la Prueba",
+  "certificates.http.warning": "Estos dominios ya deben estar configurados para apuntar a esta instalación.",
+  "certificates.request.subtitle": "con Let's Encrypt",
+  "certificates.request.title": "Solicitar un nuevo Certificado",
+  "column.access": "Acceso",
+  "column.authorization": "Autorización",
+  "column.authorizations": "Autorizaciones",
+  "column.custom-locations": "Ubicaciones Personalizadas",
+  "column.destination": "Destino",
+  "column.details": "Detalles",
+  "column.email": "Correo Electrónico",
+  "column.event": "Evento",
+  "column.expires": "Expira",
+  "column.http-code": "Código HTTP",
+  "column.incoming-port": "Puerto de Entrada",
+  "column.name": "Nombre",
+  "column.protocol": "Protocolo",
+  "column.provider": "Proveedor",
+  "column.roles": "Roles",
+  "column.rules": "Reglas",
+  "column.satisfy": "Satisfacer",
+  "column.satisfy-all": "Todo",
+  "column.satisfy-any": "Cualquiera",
+  "column.scheme": "Esquema",
+  "column.source": "Origen",
+  "column.ssl": "SSL",
+  "column.status": "Estado",
+  "created-on": "Creado: {date}",
+  "dashboard": "Panel de Control",
+  "dead-host": "Host 404",
+  "dead-hosts": "Hosts 404",
+  "dead-hosts.count": "{count} {count, plural, one {Host 404} other {Hosts 404}}",
+  "disabled": "Deshabilitado",
+  "domain-names": "Nombres de Dominio",
+  "domain-names.max": "{count} nombres de dominio como máximo",
+  "domain-names.placeholder": "Comienza a escribir para añadir dominio...",
+  "domain-names.wildcards-not-permitted": "No se permiten comodines para este tipo",
+  "domain-names.wildcards-not-supported": "No se admiten comodines para esta CA",
+  "domains.force-ssl": "Forzar SSL",
+  "domains.hsts-enabled": "HSTS Habilitado",
+  "domains.hsts-subdomains": "HSTS en Subdominios",
+  "domains.http2-support": "Soporte HTTP/2",
+  "domains.use-dns": "Usar Desafío DNS",
+  "email-address": "Dirección de correo electrónico",
+  "empty-search": "No se encontraron resultados",
+  "empty-subtitle": "¿Por qué no creas uno?",
+  "enabled": "Habilitado",
+  "error.access.at-least-one": "Se requiere al menos una Autorización o una Regla de Acceso",
+  "error.access.duplicate-usernames": "Los nombres de usuario de autorización deben ser únicos",
+  "error.invalid-auth": "Correo electrónico o contraseña no válidos",
+  "error.invalid-domain": "Dominio no válido: {domain}",
+  "error.invalid-email": "Dirección de correo electrónico no válida",
+  "error.max-character-length": "La longitud máxima es {max} caracter{max, plural, one {} other {es}}",
+  "error.max-domains": "Demasiados dominios, el máximo es {max}",
+  "error.maximum": "El máximo es {max}",
+  "error.min-character-length": "La longitud mínima es {min} caracter{min, plural, one {} other {es}}",
+  "error.minimum": "El mínimo es {min}",
+  "error.passwords-must-match": "Las contraseñas deben coincidir",
+  "error.required": "Este campo es obligatorio",
+  "expires.on": "Expira: {date}",
+  "footer.github-fork": "Bifúrcame en Github",
+  "host.flags.block-exploits": "Bloquear Exploits Comunes",
+  "host.flags.cache-assets": "Cachear Recursos",
+  "host.flags.preserve-path": "Preservar Ruta",
+  "host.flags.protocols": "Protocolos",
+  "host.flags.websockets-upgrade": "Soporte de Websockets",
+  "host.forward-port": "Puerto de Reenvío",
+  "host.forward-scheme": "Esquema",
+  "hosts": "Hosts",
+  "http-only": "Solo HTTP",
+  "lets-encrypt": "Let's Encrypt",
+  "lets-encrypt-via-dns": "Let's Encrypt vía DNS",
+  "lets-encrypt-via-http": "Let's Encrypt vía HTTP",
+  "loading": "Cargando…",
+  "login.title": "Inicia sesión en tu cuenta",
+  "nginx-config.label": "Configuración Personalizada de Nginx",
+  "nginx-config.placeholder": "# ¡Introduce aquí tu configuración personalizada de Nginx bajo tu propio riesgo!",
+  "no-permission-error": "No tienes acceso para ver esto.",
+  "notfound.action": "Llévame al inicio",
+  "notfound.content": "Lo sentimos, pero la página que buscas no fue encontrada",
+  "notfound.title": "Ups… Has encontrado una página de error",
+  "notification.error": "Error",
+  "notification.object-deleted": "{object} ha sido eliminado",
+  "notification.object-disabled": "{object} ha sido deshabilitado",
+  "notification.object-enabled": "{object} ha sido habilitado",
+  "notification.object-renewed": "{object} ha sido renovado",
+  "notification.object-saved": "{object} ha sido guardado",
+  "notification.success": "Éxito",
+  "object.actions-title": "{object} #{id}",
+  "object.add": "Añadir {object}",
+  "object.delete": "Eliminar {object}",
+  "object.delete.content": "¿Estás seguro de que quieres eliminar este {object}?",
+  "object.edit": "Editar {object}",
+  "object.empty": "No hay {objects}",
+  "object.event.created": "{object} Creado",
+  "object.event.deleted": "{object} Eliminado",
+  "object.event.disabled": "{object} Deshabilitado",
+  "object.event.enabled": "{object} Habilitado",
+  "object.event.renewed": "{object} Renovado",
+  "object.event.updated": "{object} Actualizado",
+  "offline": "Desconectado",
+  "online": "Conectado",
+  "options": "Opciones",
+  "password": "Contraseña",
+  "password.generate": "Generar contraseña aleatoria",
+  "password.hide": "Ocultar Contraseña",
+  "password.show": "Mostrar Contraseña",
+  "permissions.hidden": "Oculto",
+  "permissions.manage": "Gestionar",
+  "permissions.view": "Solo Ver",
+  "permissions.visibility.all": "Todos los Elementos",
+  "permissions.visibility.title": "Visibilidad de Elementos",
+  "permissions.visibility.user": "Solo Elementos Creados",
+  "proxy-host": "Host Proxy",
+  "proxy-host.forward-host": "Nombre de Host / IP de Reenvío",
+  "proxy-hosts": "Hosts Proxy",
+  "proxy-hosts.count": "{count} {count, plural, one {Host Proxy} other {Hosts Proxy}}",
+  "public": "Público",
+  "redirection-host": "Host de Redirección",
+  "redirection-host.forward-domain": "Dominio de Reenvío",
+  "redirection-host.forward-http-code": "Código HTTP",
+  "redirection-hosts": "Hosts de Redirección",
+  "redirection-hosts.count": "{count} {count, plural, one {Host de Redirección} other {Hosts de Redirección}}",
+  "role.admin": "Administrador",
+  "role.standard-user": "Usuario Estándar",
+  "save": "Guardar",
+  "setting": "Configuración",
+  "settings": "Configuración",
+  "settings.default-site": "Sitio Predeterminado",
+  "settings.default-site.404": "Página 404",
+  "settings.default-site.444": "Sin Respuesta (444)",
+  "settings.default-site.congratulations": "Página de Felicitaciones",
+  "settings.default-site.description": "Qué mostrar cuando Nginx recibe un Host desconocido",
+  "settings.default-site.html": "HTML Personalizado",
+  "settings.default-site.html.placeholder": "<!-- Introduce aquí tu contenido HTML personalizado -->",
+  "settings.default-site.redirect": "Redirigir",
+  "setup.preamble": "Comienza creando tu cuenta de administrador.",
+  "setup.title": "¡Bienvenido!",
+  "sign-in": "Iniciar Sesión",
+  "ssl-certificate": "Certificado SSL",
+  "stream": "Stream",
+  "stream.forward-host": "Host de Reenvío",
+  "stream.incoming-port": "Puerto de Entrada",
+  "streams": "Streams",
+  "streams.count": "{count} {count, plural, one {Stream} other {Streams}}",
+  "streams.tcp": "TCP",
+  "streams.udp": "UDP",
+  "test": "Probar",
+  "user": "Usuario",
+  "user.change-password": "Cambiar Contraseña",
+  "user.confirm-password": "Confirmar Contraseña",
+  "user.current-password": "Contraseña Actual",
+  "user.edit-profile": "Editar Perfil",
+  "user.full-name": "Nombre Completo",
+  "user.login-as": "Iniciar sesión como {name}",
+  "user.logout": "Cerrar Sesión",
+  "user.new-password": "Nueva Contraseña",
+  "user.nickname": "Apodo",
+  "user.set-password": "Establecer Contraseña",
+  "user.set-permissions": "Establecer Permisos para {name}",
+  "user.switch-dark": "Cambiar a modo Oscuro",
+  "user.switch-light": "Cambiar a modo Claro",
+  "username": "Nombre de Usuario",
+  "users": "Usuarios"
+}

+ 215 - 0
frontend/src/locale/lang/ja.json

@@ -0,0 +1,215 @@
+{
+  "access-list": "アクセスリスト",
+  "access-list.access-count": "{count} ルール",
+  "access-list.auth-count": "{count} ユーザー",
+  "access-list.help-rules-last": "少なくとも 1 つのルールが存在する場合、 他のすべてを拒否するルールが最後に追加されます",
+  "access-list.help.rules-order": "許可コマンドと拒否コマンドは定義された順番で適用されます",
+  "access-list.pass-auth": "認証情報をアップストリームに送信する",
+  "access-list.public": "公開されたアクセス",
+  "access-list.public.subtitle": "ベーシック認証を使用しません",
+  "access-list.satisfy-any": "いずれかを満たす",
+  "access-list.subtitle": "{users} ユーザー, {rules} ルール - 作成日時: {date}",
+  "access-lists": "アクセスリスト",
+  "action.add": "追加",
+  "action.add-location": "場所を追加",
+  "action.close": "閉じる",
+  "action.delete": "削除",
+  "action.disable": "無効化",
+  "action.download": "ダウンロード",
+  "action.edit": "編集",
+  "action.enable": "有効化",
+  "action.permissions": "権限",
+  "action.renew": "更新",
+  "action.view-details": "詳細",
+  "auditlogs": "監査ログ",
+  "cancel": "キャンセル",
+  "certificate": "証明書",
+  "certificate.custom-certificate": "証明書",
+  "certificate.custom-certificate-key": "証明書キー",
+  "certificate.custom-intermediate": "中間証明書",
+  "certificate.in-use": "使用中",
+  "certificate.none.subtitle": "証明書が割り当てられていません",
+  "certificate.none.subtitle.for-http": "このホストはHTTPSを使用しません",
+  "certificate.none.title": "無し",
+  "certificate.not-in-use": "未使用",
+  "certificate.renew": "証明書を更新",
+  "certificates": "証明書",
+  "certificates.custom": "カスタム証明書",
+  "certificates.custom.warning": "パスワードによって保護されたキーファイルはサポートされていません",
+  "certificates.dns.credentials": "資格情報ファイルの内容",
+  "certificates.dns.credentials-note": "このプラグインはプロバイダーのAPIキーか認証情報を含む設定ファイルが必要です",
+  "certificates.dns.credentials-warning": "このデータはファイルとデータベースにプレーンテキストとして保存されます",
+  "certificates.dns.propagation-seconds": "DNS伝播時間(秒)",
+  "certificates.dns.propagation-seconds-note": "DNSの伝搬時間を秒で指定します。空にするとデフォルトの値を使用します。",
+  "certificates.dns.provider": "DNSプロバイダー",
+  "certificates.dns.warning": "このセクションはCertbotとそのDNSプラグインの知識が必要です。各プラグインのドキュメントを参照してください。",
+  "certificates.http.reachability-404": "このドメインはNginx Proxy Managerではないサーバーを指しているようです。ドメインがこのNPMインスタンスを指していることを確認してください。",
+  "certificates.http.reachability-failed-to-check": "site24x7.comへの接続でエラーが発生し、到達性チェックに失敗しました",
+  "certificates.http.reachability-not-resolved": "このドメインには利用可能なサーバーがありません。ドメインが存在し、NPMインスタンスのIPアドレスを指していること、必要に応じてルーターでポート80が転送されていることを確認してください。",
+  "certificates.http.reachability-ok": "サーバーへ到達可能であり、証明書の作成が可能です。",
+  "certificates.http.reachability-other": "このドメインでサーバーが見つかりましたが予期しないステータスコード {code} を返しました. NPMサーバーが動いていますか? ドメインがこのNPMインスタンスを指していることを確認してください。",
+  "certificates.http.reachability-wrong-data": "このドメインでサーバーが見つかりましたが予期しないデータを返しました. NPMサーバーが動いていますか? ドメインがこのNPMインスタンスを指していることを確認してください。",
+  "certificates.http.test-results": "テスト結果",
+  "certificates.http.warning": "これらのドメインは、すでにこのインストール先を指すように設定されている必要がありますあ.",
+  "certificates.request.subtitle": "Let's Encryptを使用する",
+  "certificates.request.title": "新しい証明書を作成",
+  "column.access": "アクセス",
+  "column.authorization": "認証",
+  "column.authorizations": "認証",
+  "column.custom-locations": "カスタムロケーション",
+  "column.destination": "宛先",
+  "column.details": "詳細",
+  "column.email": "Email",
+  "column.event": "イベント",
+  "column.expires": "期限切れ",
+  "column.http-code": "アクセス",
+  "column.incoming-port": "受信ポート",
+  "column.name": "名前",
+  "column.protocol": "プロトコル",
+  "column.provider": "プロバイダー",
+  "column.roles": "Roles",
+  "column.rules": "ルール",
+  "column.satisfy": "Satisfy",
+  "column.satisfy-all": "すべて",
+  "column.satisfy-any": "いずれか",
+  "column.scheme": "スキーム",
+  "column.source": "ソース",
+  "column.ssl": "SSL",
+  "column.status": "ステータス",
+  "created-on": "作成日時: {date}",
+  "dashboard": "ダッシュボード",
+  "dead-host": "404 ホスト",
+  "dead-hosts": "404 ホスト",
+  "dead-hosts.count": "{count} 404 ホスト",
+  "disabled": "無効化",
+  "domain-names": "ドメイン名",
+  "domain-names.max": "{count}のドメイン名が最大です",
+  "domain-names.placeholder": "追加するドメインを入力...",
+  "domain-names.wildcards-not-permitted": "ワイルドカードはこのタイプでは許可されていません",
+  "domain-names.wildcards-not-supported": "ワイルドカードはこのCAではサポートされていません",
+  "domains.force-ssl": "SSLを強制",
+  "domains.hsts-enabled": "HSTSを有効化",
+  "domains.hsts-subdomains": "HSTSサブドメイン",
+  "domains.http2-support": "HTTP/2サポート",
+  "domains.use-dns": "DNSチャレンジを使用",
+  "email-address": "Emailアドレス",
+  "empty-search": "見つかりませんでした",
+  "empty-subtitle": "作ってみましょう",
+  "enabled": "有効",
+  "error.access.at-least-one": "少なくとも一つの認証またはアクセスルールが必要です",
+  "error.access.duplicate-usernames": "認証のユーザー名は他と同じ名前は使用できません",
+  "error.invalid-auth": "無効なemailまたはパスワード",
+  "error.invalid-domain": "無効なドメイン: {domain}",
+  "error.invalid-email": "無効なemailアドレス",
+  "error.max-character-length": "文字数は長くとも{max}文字です",
+  "error.max-domains": "ドメインが多すぎます, 最大値は{max}です",
+  "error.maximum": "最大値は{max}です",
+  "error.min-character-length": "文字数は少なくとも{min}文字です",
+  "error.minimum": "最小値は{min}です",
+  "error.passwords-must-match": "パスワードは一致する必要があります",
+  "error.required": "必須項目です",
+  "expires.on": "有効期限: {date}",
+  "footer.github-fork": "Fork me on Github",
+  "host.flags.block-exploits": "一般的なエクスプロイトをブロックする",
+  "host.flags.cache-assets": "アセットをキャッシュする",
+  "host.flags.preserve-path": "パスワードは一致する必要があります",
+  "host.flags.protocols": "プロトコル",
+  "host.flags.websockets-upgrade": "Websocketsサポート",
+  "host.forward-port": "転送ポート",
+  "host.forward-scheme": "スキーム",
+  "hosts": "ホスト",
+  "http-only": "HTTP Only",
+  "lets-encrypt": "Let's Encrypt",
+  "lets-encrypt-via-dns": "Let's Encrypt via DNS",
+  "lets-encrypt-via-http": "Let's Encrypt via HTTP",
+  "loading": "Loading…",
+  "login.title": "アカウントにログイン",
+  "nginx-config.label": "カスタムNginx設定",
+  "nginx-config.placeholder": "# Enter your custom Nginx configuration here at your own risk!",
+  "no-permission-error": "これを表示する権限がありません",
+  "notfound.action": "ホームに戻る",
+  "notfound.content": "申し訳ありませんが探しているページは見つかりませんでした",
+  "notfound.title": "おっと... エラーページにたどり着いてしまったようです",
+  "notification.error": "エラー",
+  "notification.object-deleted": "{object}は削除されました",
+  "notification.object-disabled": "{object}は無効化されました",
+  "notification.object-enabled": "{object}は有効化されました",
+  "notification.object-renewed": "{object}は再作成されました",
+  "notification.object-saved": "{object}は保存されました",
+  "notification.success": "成功",
+  "object.actions-title": "{object} #{id}",
+  "object.add": "{object}を追加",
+  "object.delete": "{object}を削除",
+  "object.delete.content": "本当に{object}を削除しますか?",
+  "object.edit": "{object}を編集",
+  "object.empty": "{objects}はありません",
+  "object.event.created": "{object}を作成済み",
+  "object.event.deleted": "{object}を削除済み",
+  "object.event.disabled": "{object}を無効化済み",
+  "object.event.enabled": "{object}を有効化済み",
+  "object.event.renewed": "{object}を再作成済み",
+  "object.event.updated": "{object}を更新済み",
+  "offline": "Offline",
+  "online": "Online",
+  "options": "Options",
+  "password": "パスワード",
+  "password.generate": "ランダムなパスワードを生成",
+  "password.hide": "パスワードを隠す",
+  "password.show": "パスワードを表示する",
+  "permissions.hidden": "非公開",
+  "permissions.manage": "管理",
+  "permissions.view": "表示のみ",
+  "permissions.visibility.all": "すべて",
+  "permissions.visibility.title": "可視性",
+  "permissions.visibility.user": "作成したもののみ",
+  "proxy-host": "プロキシホスト",
+  "proxy-host.forward-host": "転送ホスト名/IP",
+  "proxy-hosts": "プロキシホスト",
+  "proxy-hosts.count": "{count} プロキシホスト",
+  "public": "Public",
+  "redirection-host": "リダイレクトホスト",
+  "redirection-host.forward-domain": "転送ホスト",
+  "redirection-hosts": "リダイレクトホスト",
+  "redirection-hosts.count": "{count} リダイレクトホスト",
+  "role.admin": "管理者",
+  "role.standard-user": "一般ユーザー",
+  "save": "保存",
+  "setting": "設定",
+  "settings": "設定",
+  "settings.default-site": "デフォルトサイト",
+  "settings.default-site.404": "404ページ",
+  "settings.default-site.444": "返答しない (444)",
+  "settings.default-site.congratulations": "設定ページ",
+  "settings.default-site.description": "不明なホストを要求されたときにNginxが何を返すかを設定します",
+  "settings.default-site.html": "カスタムHTML",
+  "settings.default-site.html.placeholder": "<!-- Enter your custom HTML content here -->",
+  "settings.default-site.redirect": "リダイレクト",
+  "setup.preamble": "管理者アカウントを作成して始めましょう",
+  "setup.title": "ようこそ!",
+  "sign-in": "サインイン",
+  "ssl-certificate": "SSL証明書",
+  "stream": "ストリーム",
+  "stream.forward-host": "転送ポート",
+  "stream.incoming-port": "受信ポート",
+  "streams": "ストリーム",
+  "streams.count": "{count} ストリーム",
+  "streams.tcp": "TCP",
+  "streams.udp": "UDP",
+  "test": "テスト",
+  "user": "ユーザー",
+  "user.change-password": "変更するパスワード",
+  "user.confirm-password": "変更するパスワードを確認",
+  "user.current-password": "現在のパスワード",
+  "user.edit-profile": "プロフィールを編集",
+  "user.full-name": "フルネーム",
+  "user.login-as": "{name}としてサインイン",
+  "user.logout": "ログアウト",
+  "user.new-password": "新しいパスワード",
+  "user.nickname": "ニックネーム",
+  "user.set-password": "パスワードを設定",
+  "user.set-permissions": "{name}に権限を設定",
+  "user.switch-dark": "ダークモードに変更",
+  "user.switch-light": "ライトモードに変更",
+  "username": "ユーザー名",
+  "users": "ユーザー"
+}

+ 3 - 0
frontend/src/locale/lang/lang-list.json

@@ -1,4 +1,7 @@
 {
   "locale-en-US": "English",
+  "locale-de-DE": "German",
+  "locale-es-ES": "Español",
+  "locale-ja-JP": "日本語",
   "locale-ru-RU": "Русский"
 }

+ 7 - 0
frontend/src/locale/src/HelpDoc/de/AccessLists.md

@@ -0,0 +1,7 @@
+## Was ist eine Zugriffsliste?
+
+Zugriffslisten bieten eine Blacklist oder Whitelist mit bestimmten Client-IP-Adressen sowie eine Authentifizierung für die Proxy-Hosts über die grundlegende HTTP-Authentifizierung.
+
+Sie können mehrere Client-Regeln, Benutzernamen und Passwörter für eine einzelne Zugriffsliste konfigurieren und diese dann auf einen oder mehrere Proxy-Hosts anwenden.
+
+Dies ist besonders nützlich für weitergeleitete Webdienste, die keine integrierten Authentifizierungsmechanismen haben, oder wenn Sie sich vor unbekannten Clients schützen möchten.

+ 32 - 0
frontend/src/locale/src/HelpDoc/de/Certificates.md

@@ -0,0 +1,32 @@
+## Hilfe zu Zertifikaten
+
+### HTTP-Zertifikat
+
+Ein HTTP-validiertes Zertifikat bedeutet, dass Let's Encrypt-Server
+versuchen, Ihre Domains über HTTP (nicht HTTPS!) zu erreichen, und wenn dies erfolgreich ist,
+stellen sie Ihr Zertifikat aus.
+
+Für diese Methode müssen Sie einen _Proxy-Host_ für Ihre Domain(s) erstellen, der
+über HTTP zugänglich ist und auf diese Nginx-Installation verweist. Nachdem ein Zertifikat
+ausgestellt wurde, können Sie den _Proxy-Host_ so ändern, dass dieses Zertifikat auch für HTTPS-Verbindungen
+verwendet wird. Der _Proxy-Host_ muss jedoch weiterhin für den HTTP-Zugriff konfiguriert sein,
+ damit das Zertifikat erneuert werden kann.
+
+Dieser Prozess unterstützt keine Wildcard-Domains.
+
+### DNS-Zertifikat
+
+Für ein DNS-validiertes Zertifikat müssen Sie ein DNS-Provider-Plugin verwenden. Dieser DNS-
+Provider wird verwendet, um temporäre Einträge auf Ihrer Domain zu erstellen. Anschließend fragt Let's
+Encrypt diese Einträge ab, um sicherzustellen, dass Sie der Eigentümer sind. Bei Erfolg wird
+Ihr Zertifikat ausgestellt.
+
+Sie müssen vor der Beantragung dieser Art von Zertifikat keinen _Proxy-Host_ erstellen.
+Sie müssen Ihren _Proxy-Host_ auch nicht für den HTTP-Zugriff konfigurieren.
+
+Dieser Prozess unterstützt Wildcard-Domains.
+
+### Benutzerdefiniertes Zertifikat
+
+Verwenden Sie diese Option, um Ihr eigenes SSL-Zertifikat hochzuladen, das Ihnen von Ihrer eigenen
+Zertifizierungsstelle bereitgestellt wurde.

+ 10 - 0
frontend/src/locale/src/HelpDoc/de/DeadHosts.md

@@ -0,0 +1,10 @@
+## Was ist ein 404-Host?
+
+Ein 404-Host ist ein Host-Setup, das eine 404-Seite anzeigt.
+
+Dies kann nützlich sein, wenn Ihre Domain in Suchmaschinen gelistet ist und Sie
+eine ansprechendere Fehlerseite bereitstellen oder den Suchindexern ausdrücklich mitteilen möchten, dass
+die Domain-Seiten nicht mehr existieren.
+
+Ein weiterer Vorteil dieses Hosts besteht darin, dass Sie die Protokolle für Zugriffe darauf verfolgen und
+die Verweise anzeigen können.

+ 7 - 0
frontend/src/locale/src/HelpDoc/de/ProxyHosts.md

@@ -0,0 +1,7 @@
+## Was ist ein Proxy-Host?
+
+Ein Proxy-Host ist der eingehende Endpunkt für einen Webdienst, den Sie weiterleiten möchten.
+
+Er bietet optionale SSL-Terminierung für Ihren Dienst, der möglicherweise keine integrierte SSL-Unterstützung hat.
+
+Proxy-Hosts sind die häufigste Verwendung für den Nginx Proxy Manager.

+ 7 - 0
frontend/src/locale/src/HelpDoc/de/RedirectionHosts.md

@@ -0,0 +1,7 @@
+## Was ist ein Redirection Host?
+
+Ein Redirection Host leitet Anfragen von der eingehenden Domain weiter und leitet den
+Besucher zu einer anderen Domain weiter.
+
+Der häufigste Grund für die Verwendung dieses Host-Typs ist, wenn Ihre Website die
+Domain wechselt, aber Sie noch Suchmaschinen- oder Referrer-Links haben, die auf die alte Domain verweisen.

+ 6 - 0
frontend/src/locale/src/HelpDoc/de/Streams.md

@@ -0,0 +1,6 @@
+## Was ist ein Stream?
+
+Ein Stream ist eine relativ neue Funktion von Nginx, die dazu dient, TCP/UDP-Datenverkehr
+direkt an einen anderen Computer im Netzwerk weiterzuleiten.
+
+Wenn Sie Spielserver, FTP- oder SSH-Server betreiben, kann dies sehr nützlich sein.

+ 6 - 0
frontend/src/locale/src/HelpDoc/de/index.ts

@@ -0,0 +1,6 @@
+export * as AccessLists from "./AccessLists.md";
+export * as Certificates from "./Certificates.md";
+export * as DeadHosts from "./DeadHosts.md";
+export * as ProxyHosts from "./ProxyHosts.md";
+export * as RedirectionHosts from "./RedirectionHosts.md";
+export * as Streams from "./Streams.md";

+ 7 - 0
frontend/src/locale/src/HelpDoc/es/AccessLists.md

@@ -0,0 +1,7 @@
+## ¿Qué es una Lista de Acceso?
+
+Las Listas de Acceso proporcionan una lista negra o blanca de direcciones IP de cliente específicas junto con autenticación para los Hosts Proxy a través de Autenticación HTTP Básica.
+
+Puede configurar múltiples reglas de cliente, nombres de usuario y contraseñas para una única Lista de Acceso y luego aplicarla a uno o más _Hosts Proxy_.
+
+Esto es más útil para servicios web reenviados que no tienen mecanismos de autenticación integrados o cuando desea protegerse de clientes desconocidos.

+ 32 - 0
frontend/src/locale/src/HelpDoc/es/Certificates.md

@@ -0,0 +1,32 @@
+## Ayuda de Certificados
+
+### Certificado HTTP
+
+Un certificado validado por HTTP significa que los servidores de Let's Encrypt
+intentarán acceder a tus dominios a través de HTTP (¡no HTTPS!) y, si tienen éxito,
+emitirán tu certificado.
+
+Para este método, deberás tener un _Host Proxy_ creado para tu(s) dominio(s) que
+sea accesible por HTTP y que apunte a esta instalación de Nginx. Después de que se
+haya emitido un certificado, puedes modificar el _Host Proxy_ para que también use
+este certificado para conexiones HTTPS. Sin embargo, el _Host Proxy_ seguirá
+necesitando estar configurado para acceso HTTP para que el certificado se renueve.
+
+Este proceso _no_ admite dominios comodín.
+
+### Certificado DNS
+
+Un certificado validado por DNS requiere que uses un complemento de Proveedor de DNS.
+Este Proveedor de DNS se usará para crear registros temporales en tu dominio y luego
+Let's Encrypt consultará esos registros para asegurarse de que eres el propietario y,
+si tiene éxito, emitirá tu certificado.
+
+No necesitas tener un _Host Proxy_ creado antes de solicitar este tipo de certificado.
+Tampoco necesitas tener tu _Host Proxy_ configurado para acceso HTTP.
+
+Este proceso _sí_ admite dominios comodín.
+
+### Certificado Personalizado
+
+Usa esta opción para cargar tu propio Certificado SSL, proporcionado por tu propia
+Autoridad de Certificación.

+ 10 - 0
frontend/src/locale/src/HelpDoc/es/DeadHosts.md

@@ -0,0 +1,10 @@
+## ¿Qué es un Host 404?
+
+Un Host 404 es simplemente una configuración de host que muestra una página 404.
+
+Esto puede ser útil cuando tu dominio está listado en los motores de búsqueda y deseas
+proporcionar una página de error más agradable o específicamente para indicar a los indexadores de búsqueda que
+las páginas del dominio ya no existen.
+
+Otro beneficio de tener este host es rastrear los registros de visitas a él y
+ver los referentes.

+ 7 - 0
frontend/src/locale/src/HelpDoc/es/ProxyHosts.md

@@ -0,0 +1,7 @@
+## ¿Qué es un Host Proxy?
+
+Un Host Proxy es el punto de entrada para un servicio web que deseas reenviar.
+
+Proporciona terminación SSL opcional para tu servicio que podría no tener soporte SSL integrado.
+
+Los Hosts Proxy son el uso más común del Nginx Proxy Manager.

+ 7 - 0
frontend/src/locale/src/HelpDoc/es/RedirectionHosts.md

@@ -0,0 +1,7 @@
+## ¿Qué es un Host de Redirección?
+
+Un Host de Redirección redirigirá las solicitudes del dominio entrante e impulsará al
+visitante a otro dominio.
+
+La razón más común para usar este tipo de host es cuando tu sitio web cambia de
+dominios pero aún tienes enlaces de motores de búsqueda o referencias apuntando al dominio anterior.

+ 6 - 0
frontend/src/locale/src/HelpDoc/es/Streams.md

@@ -0,0 +1,6 @@
+## ¿Qué es un Stream?
+
+Una característica relativamente nueva para Nginx, un Stream servirá para reenviar tráfico TCP/UDP
+directamente a otra computadora en la red.
+
+Si estás ejecutando servidores de juegos, FTP o servidores SSH esto puede ser muy útil.

+ 6 - 0
frontend/src/locale/src/HelpDoc/es/index.ts

@@ -0,0 +1,6 @@
+export * as AccessLists from "./AccessLists.md";
+export * as Certificates from "./Certificates.md";
+export * as DeadHosts from "./DeadHosts.md";
+export * as ProxyHosts from "./ProxyHosts.md";
+export * as RedirectionHosts from "./RedirectionHosts.md";
+export * as Streams from "./Streams.md";

+ 11 - 5
frontend/src/locale/src/HelpDoc/index.ts

@@ -1,17 +1,23 @@
-// import * as de from "./de/index";
-// import * as fa from "./fa/index";
 import * as en from "./en/index";
+import * as de from "./de/index";
+import * as ja from "./ja/index";
 
-const items: any = { en };
+const items: any = { en, de, ja };
 
 const fallbackLang = "en";
 
 export const getHelpFile = (lang: string, section: string): string => {
-	if (typeof items[lang] !== "undefined" && typeof items[lang][section] !== "undefined") {
+	if (
+		typeof items[lang] !== "undefined" && 
+		typeof items[lang][section] !== "undefined"
+	) {
 		return items[lang][section].default;
 	}
 	// Fallback to English
-	if (typeof items[fallbackLang] !== "undefined" && typeof items[fallbackLang][section] !== "undefined") {
+	if (
+		typeof items[fallbackLang] !== "undefined" && 
+		typeof items[fallbackLang][section] !== "undefined"
+	) {
 		return items[fallbackLang][section].default;
 	}
 	throw new Error(`Cannot load help doc for ${lang}-${section}`);

+ 8 - 0
frontend/src/locale/src/HelpDoc/ja/AccessLists.md

@@ -0,0 +1,8 @@
+## アクセスリストとは
+
+アクセスリストは特定のクライアントIPへのブラックリストとホワイトリストを提供し、ベーシック認証によるプロキシホストへの認証を可能にします。
+
+複数のクライアントルールやユーザー名とパスワードを一つのアクセスリストに設定し、一つ以上の _プロキシホスト_ に適応することができます。
+
+これは認証システムを持たないサービスや不明なクライアントからの保護が必要な場合に有効です。
+

+ 21 - 0
frontend/src/locale/src/HelpDoc/ja/Certificates.md

@@ -0,0 +1,21 @@
+## 証明書
+
+### HTTP 証明書
+
+HTTPによって検証された証明書はLet's EncryptサーバーがHTTPでドメインにアクセスを試みサーバーを管理していることを確認できた場合に発行される証明書です。
+
+この方法では、HTTPアクセス可能でこのNginxを指しているドメインに対して _プロキシホスト_ を作成する必要があります。証明書が発行された後は、 _プロキシホスト_ を編集してこの証明書をHTTPS接続に使用するように設定できます。ただし、証明書の更新には、_プロキシホスト_ がHTTP接続用に設定された状態を維持する必要があります。
+
+この方法はワイルドカードのドメインをサポート _していません_ 。
+
+### DNS 証明書
+
+DNSによって検証された証明書にはDNSプロバイダープラグインが必要です。このプロバイダーはドメイン上に一時レコードを作成するために使用されます。その後Let's Encryptサーバーがそのレコードを参照し、あなたが所有していることを確認できると証明書が発行されます。
+
+このタイプの証明書を作成する際に、 _プロキシホスト_ を作成する必要はありません。また、_プロキシホスト_ をHTTPアクセス用に設定する必要もありません。
+
+この方法はワイルドカードのドメインをサポート _します_ 。
+
+### カスタム証明書
+
+このオプションでは、あなたの証明書認証局によって提供された自身の証明書をアップロードして使用できます。

+ 7 - 0
frontend/src/locale/src/HelpDoc/ja/DeadHosts.md

@@ -0,0 +1,7 @@
+## 404ホストとはなんですか?
+
+404ホストとは、単に404ページを表示するよう設定されたホストです。
+
+これは、検索エンジンに登録されたドメインに分かりやすいエラーページを提供したい場合や、検索エンジンのインデクサーにドメインページがもう存在しないことを伝えたい場合に便利です。
+
+このホストを持つもう一つの利点は、アクセスログを追跡し、参照元を確認できることです。

+ 7 - 0
frontend/src/locale/src/HelpDoc/ja/ProxyHosts.md

@@ -0,0 +1,7 @@
+## プロキシホストとは何ですか?
+
+プロキシホストは転送したいwebサービスの受信エンドポイントです。
+
+サービスにSSLサーバーが組み込まれていない場合でも、オプションでSSL終端機能を提供します。
+
+プロキシホストはNginx Proxy Managerのもっとも一般的な使用方法です。

+ 5 - 0
frontend/src/locale/src/HelpDoc/ja/RedirectionHosts.md

@@ -0,0 +1,5 @@
+## リダイレクトホストとは何ですか?
+
+リダイレクトホストは受信したリクエストを別のドメインにリダイレクトして訪問者に表示します。
+
+このタイプのもっとも一般的な使用理由は、webサイトのドメインが変更されたが検索エンジンやリンクが古いドメインを指し続けている場合です。

+ 5 - 0
frontend/src/locale/src/HelpDoc/ja/Streams.md

@@ -0,0 +1,5 @@
+## ストリームとは何ですか?
+
+Nginxの比較的新しい機能であるストリームは、TCP/UDPトラフィックをネットワーク上の別のコンピュータに直接転送します。
+
+ゲームサーバー、FTPサーバー、SSHサーバーを運用している場合に便利です。

+ 6 - 0
frontend/src/locale/src/HelpDoc/ja/index.ts

@@ -0,0 +1,6 @@
+export * as AccessLists from "./AccessLists.md";
+export * as Certificates from "./Certificates.md";
+export * as DeadHosts from "./DeadHosts.md";
+export * as ProxyHosts from "./ProxyHosts.md";
+export * as RedirectionHosts from "./RedirectionHosts.md";
+export * as Streams from "./Streams.md";

+ 644 - 0
frontend/src/locale/src/de.json

@@ -0,0 +1,644 @@
+{
+	"access-list": {
+		"defaultMessage": "Zugriffsliste"
+	},
+	"access-list.access-count": {
+		"defaultMessage": "{count} {count, plural, one {Regel} other {Regeln}}"
+	},
+	"access-list.auth-count": {
+		"defaultMessage": "{count} {count, plural, one {User} other {Users}}"
+	},
+	"access-list.help-rules-last": {
+		"defaultMessage": "Wenn mindestens eine Regel vorhanden ist, wird diese Regel zum Ablehnen aller Anfragen als letzte hinzugefügt."
+	},
+	"access-list.help.rules-order": {
+		"defaultMessage": "Beachten Sie, dass die Anweisungen „Erlauben“ und „Verbieten“ in der Reihenfolge ihrer Definition angewendet werden."
+	},
+	"access-list.pass-auth": {
+		"defaultMessage": "Authentifizierung an Upstream weiterleiten"
+	},
+	"access-list.public": {
+		"defaultMessage": "Öffentlich"
+	},
+	"access-list.public.subtitle": {
+		"defaultMessage": "Keine Authentifizierung erforderlich"
+	},
+	"access-list.satisfy-any": {
+		"defaultMessage": "Satisfy Any"
+	},
+	"access-list.subtitle": {
+		"defaultMessage": "{users} {users, plural, one {User} other {Users}}, {rules} {rules, plural, one {Regel} other {Regeln}} - Erstellt: {date}"
+	},
+	"access-lists": {
+		"defaultMessage": "Zugrifflisten"
+	},
+	"action.add": {
+		"defaultMessage": "Hinzufügen"
+	},
+	"action.add-location": {
+		"defaultMessage": "Pfad Hinzufügen"
+	},
+	"action.close": {
+		"defaultMessage": "Schließen"
+	},
+	"action.delete": {
+		"defaultMessage": "Löschen"
+	},
+	"action.disable": {
+		"defaultMessage": "Deaktivieren"
+	},
+	"action.download": {
+		"defaultMessage": "Herunterladen"
+	},
+	"action.edit": {
+		"defaultMessage": "Bearbeiten"
+	},
+	"action.enable": {
+		"defaultMessage": "Aktivieren"
+	},
+	"action.permissions": {
+		"defaultMessage": "Berechtigungen"
+	},
+	"action.renew": {
+		"defaultMessage": "Erneuert"
+	},
+	"action.view-details": {
+		"defaultMessage": "Details"
+	},
+	"auditlogs": {
+		"defaultMessage": "Protokoll"
+	},
+	"cancel": {
+		"defaultMessage": "Abbrechen"
+	},
+	"certificate": {
+		"defaultMessage": "Zertifikat"
+	},
+	"certificate.custom-certificate": {
+		"defaultMessage": "Zertifikat"
+	},
+	"certificate.custom-certificate-key": {
+		"defaultMessage": "Privater Schlüssel"
+	},
+	"certificate.custom-intermediate": {
+		"defaultMessage": "Zwischen Zertifikat"
+	},
+	"certificate.in-use": {
+		"defaultMessage": "In Benutzung"
+	},
+	"certificate.none.subtitle": {
+		"defaultMessage": "Kein Zertifikat zugewiesen"
+	},
+	"certificate.none.subtitle.for-http": {
+		"defaultMessage": "Dieser Host verwendet kein HTTPS."
+	},
+	"certificate.none.title": {
+		"defaultMessage": "Kein"
+	},
+	"certificate.not-in-use": {
+		"defaultMessage": "Nicht in Benutzung"
+	},
+	"certificate.renew": {
+		"defaultMessage": "Zertifikat erneuern"
+	},
+	"certificates": {
+		"defaultMessage": "Zertifikate"
+	},
+	"certificates.custom": {
+		"defaultMessage": "Benutzerdefiniertes Zertifikat"
+	},
+	"certificates.custom.warning": {
+		"defaultMessage": "Mit einem Passwort geschützte Schlüsseldateien werden nicht unterstützt."
+	},
+	"certificates.dns.credentials": {
+		"defaultMessage": "Inhalt der Anmeldedaten-Datei"
+	},
+	"certificates.dns.credentials-note": {
+		"defaultMessage": "Dieses Plugin erfordert eine Konfigurationsdatei, die einen API-Token oder andere Anmeldedaten für Ihren Anbieter enthält."
+	},
+	"certificates.dns.credentials-warning": {
+		"defaultMessage": "Diese Daten werden als Klartext in der Datenbank und in einer Datei gespeichert!"
+	},
+	"certificates.dns.propagation-seconds": {
+		"defaultMessage": "Wartzeit in Sekunden"
+	},
+	"certificates.dns.propagation-seconds-note": {
+		"defaultMessage": "Leer lassen um die Standardwartezeit des Plugins zu nutzen"
+	},
+	"certificates.dns.provider": {
+		"defaultMessage": "DNS Provider"
+	},
+	"certificates.dns.warning": {
+		"defaultMessage": "Dieser Abschnitt erfordert einige Kenntnisse über Certbot und seine DNS-Plugins. Bitte konsultieren Sie die jeweilige Plugin-Dokumentation."
+	},
+	"certificates.http.reachability-404": {
+		"defaultMessage": "Unter dieser Domain wurde ein Server gefunden, aber es scheint sich nicht um Nginx Proxy Manager zu handeln. Bitte stellen Sie sicher, dass Ihre Domain auf die IP-Adresse verweist, unter der Ihre NPM-Instanz ausgeführt wird."
+	},
+	"certificates.http.reachability-failed-to-check": {
+		"defaultMessage": "Die Erreichbarkeit konnte aufgrund eines Kommunikationsfehlers mit site24x7.com nicht überprüft werden."
+	},
+	"certificates.http.reachability-not-resolved": {
+		"defaultMessage": "Unter dieser Domain ist kein Server verfügbar. Bitte stellen Sie sicher, dass Ihre Domain existiert und auf die IP-Adresse verweist, unter der Ihre NPM-Instanz läuft, und dass gegebenenfalls Port 80 in Ihrem Router weitergeleitet wird."
+	},
+	"certificates.http.reachability-ok": {
+		"defaultMessage": "Ihr Server ist erreichbar und die Erstellung von Zertifikaten sollte möglich sein."
+	},
+	"certificates.http.reachability-other": {
+		"defaultMessage": "Unter dieser Domain wurde ein Server gefunden, der jedoch einen unerwarteten Statuscode {code} zurückgegeben hat. Handelt es sich um den NPM-Server? Bitte stellen Sie sicher, dass Ihre Domain auf die IP-Adresse verweist, unter der Ihre NPM-Instanz ausgeführt wird."
+	},
+	"certificates.http.reachability-wrong-data": {
+		"defaultMessage": "Unter dieser Domain wurde ein Server gefunden, der jedoch unerwartete Daten zurückgegeben hat. Handelt es sich um den NPM-Server? Bitte stellen Sie sicher, dass Ihre Domain auf die IP-Adresse verweist, unter der Ihre NPM-Instanz ausgeführt wird."
+	},
+	"certificates.http.test-results": {
+		"defaultMessage": "Test Ergeniss"
+	},
+	"certificates.http.warning": {
+		"defaultMessage": "Diese Domänen müssen bereits so konfiguriert sein, dass sie auf diese Installation verweisen."
+	},
+	"certificates.request.subtitle": {
+		"defaultMessage": "Über Let's Encrypt"
+	},
+	"certificates.request.title": {
+		"defaultMessage": "Anfordern eines neuen Zertifikates"
+	},
+	"column.access": {
+		"defaultMessage": "Zugriff"
+	},
+	"column.authorization": {
+		"defaultMessage": "Genehmigung"
+	},
+	"column.authorizations": {
+		"defaultMessage": "Genehmigungen"
+	},
+	"column.custom-locations": {
+		"defaultMessage": "Benutzerdefinierte Pfad"
+	},
+	"column.destination": {
+		"defaultMessage": "Ziel"
+	},
+	"column.details": {
+		"defaultMessage": "Details"
+	},
+	"column.email": {
+		"defaultMessage": "Email"
+	},
+	"column.event": {
+		"defaultMessage": "Ereignis"
+	},
+	"column.expires": {
+		"defaultMessage": "Verfällt am"
+	},
+	"column.http-code": {
+		"defaultMessage": "HTTP Code"
+	},
+	"column.incoming-port": {
+		"defaultMessage": "Eingehender Port"
+	},
+	"column.name": {
+		"defaultMessage": "Name"
+	},
+	"column.protocol": {
+		"defaultMessage": "Protokoll"
+	},
+	"column.provider": {
+		"defaultMessage": "Provider"
+	},
+	"column.roles": {
+		"defaultMessage": "Rollen"
+	},
+	"column.rules": {
+		"defaultMessage": "Regeln"
+	},
+	"column.satisfy": {
+		"defaultMessage": "Satisfy"
+	},
+	"column.satisfy-all": {
+		"defaultMessage": "Alle"
+	},
+	"column.satisfy-any": {
+		"defaultMessage": "Jeder"
+	},
+	"column.scheme": {
+		"defaultMessage": "Schema"
+	},
+	"column.source": {
+		"defaultMessage": "Quelle"
+	},
+	"column.ssl": {
+		"defaultMessage": "SSL"
+	},
+	"column.status": {
+		"defaultMessage": "Status"
+	},
+	"created-on": {
+		"defaultMessage": "Erstelldatum: {date}"
+	},
+	"dashboard": {
+		"defaultMessage": "Dashboard"
+	},
+	"dead-host": {
+		"defaultMessage": "404 Host"
+	},
+	"dead-hosts": {
+		"defaultMessage": "404 Hosts"
+	},
+	"dead-hosts.count": {
+		"defaultMessage": "{count} {count, plural, one {404 Host} other {404 Hosts}}"
+	},
+	"disabled": {
+		"defaultMessage": "Deaktiviert"
+	},
+	"domain-names": {
+		"defaultMessage": "Domain Names"
+	},
+	"domain-names.max": {
+		"defaultMessage": "{count} Maximale Anzahl von Domainnamen"
+	},
+	"domain-names.placeholder": {
+		"defaultMessage": "Eintragen der Domain..."
+	},
+	"domain-names.wildcards-not-permitted": {
+		"defaultMessage": "Wildcards sind für diesen Typ nicht zulässig."
+	},
+	"domain-names.wildcards-not-supported": {
+		"defaultMessage": "Wildcards werden für diese Zertifizierungsstelle nicht unterstützt."
+	},
+	"domains.force-ssl": {
+		"defaultMessage": "Erzwinge SSL"
+	},
+	"domains.hsts-enabled": {
+		"defaultMessage": "HSTS aktiviert"
+	},
+	"domains.hsts-subdomains": {
+		"defaultMessage": "HSTS Sub-domains"
+	},
+	"domains.http2-support": {
+		"defaultMessage": "HTTP/2 Support"
+	},
+	"domains.use-dns": {
+		"defaultMessage": "Nutze DNS Challenge"
+	},
+	"email-address": {
+		"defaultMessage": "Email Addresse"
+	},
+	"empty-search": {
+		"defaultMessage": "Keine Ergebnisse gefunden"
+	},
+	"empty-subtitle": {
+		"defaultMessage": "Warum erstellen Sie nicht eine?"
+	},
+	"enabled": {
+		"defaultMessage": "aktiviert"
+	},
+	"error.access.at-least-one": {
+		"defaultMessage": "Entweder eine Genehmigung oder eine Zugriffsregel ist erforderlich."
+	},
+	"error.access.duplicate-usernames": {
+		"defaultMessage": "Autorisierung Benutzernamen müssen eindeutig sein"
+	},
+	"error.invalid-auth": {
+		"defaultMessage": "Ungültige E-Mail-Adresse oder Passwort"
+	},
+	"error.invalid-domain": {
+		"defaultMessage": "Ungültige Domain: {domain}"
+	},
+	"error.invalid-email": {
+		"defaultMessage": "Ungültige E-Mail-Adresse"
+	},
+	"error.max-character-length": {
+		"defaultMessage": "Die maximale Länge beträgt {max} Zeichen{max, plural, one {} other {s}}"
+	},
+	"error.max-domains": {
+		"defaultMessage": "Zu viele Domains, maximal sind {max}"
+	},
+	"error.maximum": {
+		"defaultMessage": "Maximum ist {max}"
+	},
+	"error.min-character-length": {
+		"defaultMessage": "Die minimale Länge beträgt {min} Zeichen{min, plural, one {} other {s}}"
+	},
+	"error.minimum": {
+		"defaultMessage": "Minimum ist {min}"
+	},
+	"error.passwords-must-match": {
+		"defaultMessage": "Passwörter müssen übereinstimmen"
+	},
+	"error.required": {
+		"defaultMessage": "Dies ist erforderlich."
+	},
+	"expires.on": {
+		"defaultMessage": "Ablauf am: {date}"
+	},
+	"footer.github-fork": {
+		"defaultMessage": "Fork me on Github"
+	},
+	"host.flags.block-exploits": {
+		"defaultMessage": "Gängige Exploits blockieren"
+	},
+	"host.flags.cache-assets": {
+		"defaultMessage": "Cache Assets"
+	},
+	"host.flags.preserve-path": {
+		"defaultMessage": "Pfad beibehalten"
+	},
+	"host.flags.protocols": {
+		"defaultMessage": "Protokole"
+	},
+	"host.flags.websockets-upgrade": {
+		"defaultMessage": "Websockets Support"
+	},
+	"host.forward-port": {
+		"defaultMessage": "Forward Port"
+	},
+	"host.forward-scheme": {
+		"defaultMessage": "Schema"
+	},
+	"hosts": {
+		"defaultMessage": "Hosts"
+	},
+	"http-only": {
+		"defaultMessage": "HTTP Only"
+	},
+	"lets-encrypt": {
+		"defaultMessage": "Let's Encrypt"
+	},
+	"lets-encrypt-via-dns": {
+		"defaultMessage": "Let's Encrypt via DNS"
+	},
+	"lets-encrypt-via-http": {
+		"defaultMessage": "Let's Encrypt via HTTP"
+	},
+	"loading": {
+		"defaultMessage": "Laden…"
+	},
+	"login.title": {
+		"defaultMessage": "Account Login"
+	},
+	"nginx-config.label": {
+		"defaultMessage": "Benutzerdefinierte Nginx Konfiguration"
+	},
+	"nginx-config.placeholder": {
+		"defaultMessage": "# Geben Sie hier Ihre benutzerdefinierte Nginx-Konfiguration auf eigene Gefahr ein!"
+	},
+	"no-permission-error": {
+		"defaultMessage": "Sie haben keinen Zugriff, um dies anzuzeigen."
+	},
+	"notfound.action": {
+		"defaultMessage": "Take me home"
+	},
+	"notfound.content": {
+		"defaultMessage": "We are sorry but the page you are looking for was not found"
+	},
+	"notfound.title": {
+		"defaultMessage": "Oops… You just found an error page"
+	},
+	"notification.error": {
+		"defaultMessage": "Error"
+	},
+	"notification.object-deleted": {
+		"defaultMessage": "{object} wurde gelöscht"
+	},
+	"notification.object-disabled": {
+		"defaultMessage": "{object} wurde deaktiviert"
+	},
+	"notification.object-enabled": {
+		"defaultMessage": "{object} wurde aktiviert"
+	},
+	"notification.object-renewed": {
+		"defaultMessage": "{object} wurde erneuert"
+	},
+	"notification.object-saved": {
+		"defaultMessage": "{object} wurde gespeichert"
+	},
+	"notification.success": {
+		"defaultMessage": "Erfolgreich"
+	},
+	"object.actions-title": {
+		"defaultMessage": "{object} #{id}"
+	},
+	"object.add": {
+		"defaultMessage": "{object} hinzufügen"
+	},
+	"object.delete": {
+		"defaultMessage": "{object} löschen"
+	},
+	"object.delete.content": {
+		"defaultMessage": "Bist du dir sicher das du diese(n) {object} löschen möchtest?"
+	},
+	"object.edit": {
+		"defaultMessage": "{object} bearbeiten"
+	},
+	"object.empty": {
+		"defaultMessage": "Keine {objects} vorhanden"
+	},
+	"object.event.created": {
+		"defaultMessage": "{object} erstellt"
+	},
+	"object.event.deleted": {
+		"defaultMessage": "{object} gelöscht"
+	},
+	"object.event.disabled": {
+		"defaultMessage": "{object} deaktiviert"
+	},
+	"object.event.enabled": {
+		"defaultMessage": "{object} aktiviert"
+	},
+	"object.event.renewed": {
+		"defaultMessage": "{object} erneuert"
+	},
+	"object.event.updated": {
+		"defaultMessage": "{object} aktualisiert"
+	},
+	"offline": {
+		"defaultMessage": "Offline"
+	},
+	"online": {
+		"defaultMessage": "Online"
+	},
+	"options": {
+		"defaultMessage": "Optionen"
+	},
+	"password": {
+		"defaultMessage": "Passwort"
+	},
+	"password.generate": {
+		"defaultMessage": "Zufälliges Passwort generieren"
+	},
+	"password.hide": {
+		"defaultMessage": "Passwort verstecken"
+	},
+	"password.show": {
+		"defaultMessage": "Passwort anzeigen"
+	},
+	"permissions.hidden": {
+		"defaultMessage": "Versteckt"
+	},
+	"permissions.manage": {
+		"defaultMessage": "Verwalten"
+	},
+	"permissions.view": {
+		"defaultMessage": "Nur anzeigen"
+	},
+	"permissions.visibility.all": {
+		"defaultMessage": "Alle Elemente"
+	},
+	"permissions.visibility.title": {
+		"defaultMessage": "Objekt Sichtbarkeit"
+	},
+	"permissions.visibility.user": {
+		"defaultMessage": "Nur erstellte Elemente"
+	},
+	"proxy-host": {
+		"defaultMessage": "Proxy Host"
+	},
+	"proxy-host.forward-host": {
+		"defaultMessage": "Forward Hostname / IP"
+	},
+	"proxy-hosts": {
+		"defaultMessage": "Proxy Hosts"
+	},
+	"proxy-hosts.count": {
+		"defaultMessage": "{count} {count, plural, one {Proxy Host} other {Proxy Hosts}}"
+	},
+	"public": {
+		"defaultMessage": "Öffentlich"
+	},
+	"redirection-host": {
+		"defaultMessage": "Redirection Host"
+	},
+	"redirection-host.forward-domain": {
+		"defaultMessage": "Forward Domain"
+	},
+	"redirection-host.forward-http-code": {
+		"defaultMessage": "HTTP Code"
+	},
+	"redirection-hosts": {
+		"defaultMessage": "Redirection Hosts"
+	},
+	"redirection-hosts.count": {
+		"defaultMessage": "{count} {count, plural, one {Redirection Host} other {Redirection Hosts}}"
+	},
+	"role.admin": {
+		"defaultMessage": "Administrator"
+	},
+	"role.standard-user": {
+		"defaultMessage": "Standard User"
+	},
+	"save": {
+		"defaultMessage": "Speichern"
+	},
+	"setting": {
+		"defaultMessage": "Einstellung"
+	},
+	"settings": {
+		"defaultMessage": "Einstellungen"
+	},
+	"settings.default-site": {
+		"defaultMessage": "Standard Seite"
+	},
+	"settings.default-site.404": {
+		"defaultMessage": "404 Page"
+	},
+	"settings.default-site.444": {
+		"defaultMessage": "No Response (444)"
+	},
+	"settings.default-site.congratulations": {
+		"defaultMessage": "Willkommensseite"
+	},
+	"settings.default-site.description": {
+		"defaultMessage": "Was angezeigt wird, wenn der Nginx eine unbekannte Webseitenanfrage bekommt"
+	},
+	"settings.default-site.html": {
+		"defaultMessage": "Benutzerdefinierte HTML"
+	},
+	"settings.default-site.html.placeholder": {
+		"defaultMessage": "<!-- Geben Sie hier Ihren benutzerdefinierten HTML-Inhalt ein. -->"
+	},
+	"settings.default-site.redirect": {
+		"defaultMessage": "Weiterleitung"
+	},
+	"setup.preamble": {
+		"defaultMessage": "Beginnen Sie mit der Erstellung Ihres Administratorkontos."
+	},
+	"setup.title": {
+		"defaultMessage": "Willkommen!"
+	},
+	"sign-in": {
+		"defaultMessage": "Login"
+	},
+	"ssl-certificate": {
+		"defaultMessage": "SSL Zertifikate"
+	},
+	"stream": {
+		"defaultMessage": "Stream"
+	},
+	"stream.forward-host": {
+		"defaultMessage": "Forward Host"
+	},
+	"stream.incoming-port": {
+		"defaultMessage": "Incoming Port"
+	},
+	"streams": {
+		"defaultMessage": "Streams"
+	},
+	"streams.count": {
+		"defaultMessage": "{count} {count, plural, one {Stream} other {Streams}}"
+	},
+	"streams.tcp": {
+		"defaultMessage": "TCP"
+	},
+	"streams.udp": {
+		"defaultMessage": "UDP"
+	},
+	"test": {
+		"defaultMessage": "Test"
+	},
+	"user": {
+		"defaultMessage": "User"
+	},
+	"user.change-password": {
+		"defaultMessage": "Passwort ändern"
+	},
+	"user.confirm-password": {
+		"defaultMessage": "Passwort wiederholen"
+	},
+	"user.current-password": {
+		"defaultMessage": "Aktuelles Passwort"
+	},
+	"user.edit-profile": {
+		"defaultMessage": "Profil bearbeiten"
+	},
+	"user.full-name": {
+		"defaultMessage": "Name"
+	},
+	"user.login-as": {
+		"defaultMessage": "Einloggen als {name}"
+	},
+	"user.logout": {
+		"defaultMessage": "Ausloggen"
+	},
+	"user.new-password": {
+		"defaultMessage": "Neues Password"
+	},
+	"user.nickname": {
+		"defaultMessage": "Nickname"
+	},
+	"user.set-password": {
+		"defaultMessage": "Passwort setzen"
+	},
+	"user.set-permissions": {
+		"defaultMessage": "Berechtigungen für {name} setzen"
+	},
+	"user.switch-dark": {
+		"defaultMessage": "Zum Dark Mode wechseln"
+	},
+	"user.switch-light": {
+		"defaultMessage": "Zum Light Mode wechslen"
+	},
+	"username": {
+		"defaultMessage": "Benutzername"
+	},
+	"users": {
+		"defaultMessage": "Benutzer"
+	}
+}

+ 4 - 1
frontend/src/locale/src/en.json

@@ -189,7 +189,7 @@
 		"defaultMessage": "Expires"
 	},
 	"column.http-code": {
-		"defaultMessage": "Access"
+		"defaultMessage": "HTTP Code"
 	},
 	"column.incoming-port": {
 		"defaultMessage": "Incoming Port"
@@ -509,6 +509,9 @@
 	"redirection-host.forward-domain": {
 		"defaultMessage": "Forward Domain"
 	},
+	"redirection-host.forward-http-code": {
+		"defaultMessage": "HTTP Code"
+	},
 	"redirection-hosts": {
 		"defaultMessage": "Redirection Hosts"
 	},

+ 644 - 0
frontend/src/locale/src/es.json

@@ -0,0 +1,644 @@
+{
+	"access-list": {
+		"defaultMessage": "Lista de Acceso"
+	},
+	"access-list.access-count": {
+		"defaultMessage": "{count} {count, plural, one {Regla} other {Reglas}}"
+	},
+	"access-list.auth-count": {
+		"defaultMessage": "{count} {count, plural, one {Usuario} other {Usuarios}}"
+	},
+	"access-list.help-rules-last": {
+		"defaultMessage": "Cuando exista al menos 1 regla, esta regla de denegar todo se añadirá al final"
+	},
+	"access-list.help.rules-order": {
+		"defaultMessage": "Ten en cuenta que las directivas de permitir y denegar se aplicarán en el orden en que estén definidas."
+	},
+	"access-list.pass-auth": {
+		"defaultMessage": "Pasar Autenticación al Upstream"
+	},
+	"access-list.public": {
+		"defaultMessage": "Accesible Públicamente"
+	},
+	"access-list.public.subtitle": {
+		"defaultMessage": "No se requiere autenticación básica"
+	},
+	"access-list.satisfy-any": {
+		"defaultMessage": "Satisfacer Cualquiera"
+	},
+	"access-list.subtitle": {
+		"defaultMessage": "{users} {users, plural, one {Usuario} other {Usuarios}}, {rules} {rules, plural, one {Regla} other {Reglas}} - Creado: {date}"
+	},
+	"access-lists": {
+		"defaultMessage": "Listas de Acceso"
+	},
+	"action.add": {
+		"defaultMessage": "Añadir"
+	},
+	"action.add-location": {
+		"defaultMessage": "Añadir Ubicación"
+	},
+	"action.close": {
+		"defaultMessage": "Cerrar"
+	},
+	"action.delete": {
+		"defaultMessage": "Eliminar"
+	},
+	"action.disable": {
+		"defaultMessage": "Deshabilitar"
+	},
+	"action.download": {
+		"defaultMessage": "Descargar"
+	},
+	"action.edit": {
+		"defaultMessage": "Editar"
+	},
+	"action.enable": {
+		"defaultMessage": "Habilitar"
+	},
+	"action.permissions": {
+		"defaultMessage": "Permisos"
+	},
+	"action.renew": {
+		"defaultMessage": "Renovar"
+	},
+	"action.view-details": {
+		"defaultMessage": "Ver Detalles"
+	},
+	"auditlogs": {
+		"defaultMessage": "Registros de Auditoría"
+	},
+	"cancel": {
+		"defaultMessage": "Cancelar"
+	},
+	"certificate": {
+		"defaultMessage": "Certificado"
+	},
+	"certificate.custom-certificate": {
+		"defaultMessage": "Certificado"
+	},
+	"certificate.custom-certificate-key": {
+		"defaultMessage": "Clave del Certificado"
+	},
+	"certificate.custom-intermediate": {
+		"defaultMessage": "Certificado Intermedio"
+	},
+	"certificate.in-use": {
+		"defaultMessage": "En Uso"
+	},
+	"certificate.none.subtitle": {
+		"defaultMessage": "Sin certificado asignado"
+	},
+	"certificate.none.subtitle.for-http": {
+		"defaultMessage": "Este host no usará HTTPS"
+	},
+	"certificate.none.title": {
+		"defaultMessage": "Ninguno"
+	},
+	"certificate.not-in-use": {
+		"defaultMessage": "Sin Usar"
+	},
+	"certificate.renew": {
+		"defaultMessage": "Renovar Certificado"
+	},
+	"certificates": {
+		"defaultMessage": "Certificados"
+	},
+	"certificates.custom": {
+		"defaultMessage": "Certificado Personalizado"
+	},
+	"certificates.custom.warning": {
+		"defaultMessage": "No se admiten archivos de claves protegidos con contraseña."
+	},
+	"certificates.dns.credentials": {
+		"defaultMessage": "Contenido del Archivo de Credenciales"
+	},
+	"certificates.dns.credentials-note": {
+		"defaultMessage": "Este plugin requiere un archivo de configuración que contenga un token de API u otras credenciales para tu proveedor"
+	},
+	"certificates.dns.credentials-warning": {
+		"defaultMessage": "¡Estos datos se almacenarán como texto plano en la base de datos y en un archivo!"
+	},
+	"certificates.dns.propagation-seconds": {
+		"defaultMessage": "Segundos de Propagación"
+	},
+	"certificates.dns.propagation-seconds-note": {
+		"defaultMessage": "Dejar vacío para usar el valor predeterminado del plugin. Número de segundos a esperar para la propagación DNS."
+	},
+	"certificates.dns.provider": {
+		"defaultMessage": "Proveedor DNS"
+	},
+	"certificates.dns.warning": {
+		"defaultMessage": "Esta sección requiere algunos conocimientos sobre Certbot y sus plugins DNS. Consulta la documentación de los plugins respectivos."
+	},
+	"certificates.http.reachability-404": {
+		"defaultMessage": "Se encontró un servidor en este dominio pero no parece ser Nginx Proxy Manager. Asegúrate de que tu dominio apunte a la IP donde se está ejecutando tu instancia de NPM."
+	},
+	"certificates.http.reachability-failed-to-check": {
+		"defaultMessage": "No se pudo verificar la accesibilidad debido a un error de comunicación con site24x7.com."
+	},
+	"certificates.http.reachability-not-resolved": {
+		"defaultMessage": "No hay ningún servidor disponible en este dominio. Asegúrate de que tu dominio existe y apunta a la IP donde se está ejecutando tu instancia de NPM y, si es necesario, que el puerto 80 esté redirigido en tu router."
+	},
+	"certificates.http.reachability-ok": {
+		"defaultMessage": "Tu servidor es accesible y debería ser posible crear certificados."
+	},
+	"certificates.http.reachability-other": {
+		"defaultMessage": "Se encontró un servidor en este dominio pero devolvió un código de estado inesperado {code}. ¿Es el servidor NPM? Asegúrate de que tu dominio apunte a la IP donde se está ejecutando tu instancia de NPM."
+	},
+	"certificates.http.reachability-wrong-data": {
+		"defaultMessage": "Se encontró un servidor en este dominio pero devolvió datos inesperados. ¿Es el servidor NPM? Asegúrate de que tu dominio apunte a la IP donde se está ejecutando tu instancia de NPM."
+	},
+	"certificates.http.test-results": {
+		"defaultMessage": "Resultados de la Prueba"
+	},
+	"certificates.http.warning": {
+		"defaultMessage": "Estos dominios ya deben estar configurados para apuntar a esta instalación."
+	},
+	"certificates.request.subtitle": {
+		"defaultMessage": "con Let's Encrypt"
+	},
+	"certificates.request.title": {
+		"defaultMessage": "Solicitar un nuevo Certificado"
+	},
+	"column.access": {
+		"defaultMessage": "Acceso"
+	},
+	"column.authorization": {
+		"defaultMessage": "Autorización"
+	},
+	"column.authorizations": {
+		"defaultMessage": "Autorizaciones"
+	},
+	"column.custom-locations": {
+		"defaultMessage": "Ubicaciones Personalizadas"
+	},
+	"column.destination": {
+		"defaultMessage": "Destino"
+	},
+	"column.details": {
+		"defaultMessage": "Detalles"
+	},
+	"column.email": {
+		"defaultMessage": "Correo Electrónico"
+	},
+	"column.event": {
+		"defaultMessage": "Evento"
+	},
+	"column.expires": {
+		"defaultMessage": "Expira"
+	},
+	"column.http-code": {
+		"defaultMessage": "Código HTTP"
+	},
+	"column.incoming-port": {
+		"defaultMessage": "Puerto de Entrada"
+	},
+	"column.name": {
+		"defaultMessage": "Nombre"
+	},
+	"column.protocol": {
+		"defaultMessage": "Protocolo"
+	},
+	"column.provider": {
+		"defaultMessage": "Proveedor"
+	},
+	"column.roles": {
+		"defaultMessage": "Roles"
+	},
+	"column.rules": {
+		"defaultMessage": "Reglas"
+	},
+	"column.satisfy": {
+		"defaultMessage": "Satisfacer"
+	},
+	"column.satisfy-all": {
+		"defaultMessage": "Todo"
+	},
+	"column.satisfy-any": {
+		"defaultMessage": "Cualquiera"
+	},
+	"column.scheme": {
+		"defaultMessage": "Esquema"
+	},
+	"column.source": {
+		"defaultMessage": "Origen"
+	},
+	"column.ssl": {
+		"defaultMessage": "SSL"
+	},
+	"column.status": {
+		"defaultMessage": "Estado"
+	},
+	"created-on": {
+		"defaultMessage": "Creado: {date}"
+	},
+	"dashboard": {
+		"defaultMessage": "Panel de Control"
+	},
+	"dead-host": {
+		"defaultMessage": "Host 404"
+	},
+	"dead-hosts": {
+		"defaultMessage": "Hosts 404"
+	},
+	"dead-hosts.count": {
+		"defaultMessage": "{count} {count, plural, one {Host 404} other {Hosts 404}}"
+	},
+	"disabled": {
+		"defaultMessage": "Deshabilitado"
+	},
+	"domain-names": {
+		"defaultMessage": "Nombres de Dominio"
+	},
+	"domain-names.max": {
+		"defaultMessage": "{count} nombres de dominio como máximo"
+	},
+	"domain-names.placeholder": {
+		"defaultMessage": "Comienza a escribir para añadir dominio..."
+	},
+	"domain-names.wildcards-not-permitted": {
+		"defaultMessage": "No se permiten comodines para este tipo"
+	},
+	"domain-names.wildcards-not-supported": {
+		"defaultMessage": "No se admiten comodines para esta CA"
+	},
+	"domains.force-ssl": {
+		"defaultMessage": "Forzar SSL"
+	},
+	"domains.hsts-enabled": {
+		"defaultMessage": "HSTS Habilitado"
+	},
+	"domains.hsts-subdomains": {
+		"defaultMessage": "HSTS en Subdominios"
+	},
+	"domains.http2-support": {
+		"defaultMessage": "Soporte HTTP/2"
+	},
+	"domains.use-dns": {
+		"defaultMessage": "Usar Desafío DNS"
+	},
+	"email-address": {
+		"defaultMessage": "Dirección de correo electrónico"
+	},
+	"empty-search": {
+		"defaultMessage": "No se encontraron resultados"
+	},
+	"empty-subtitle": {
+		"defaultMessage": "¿Por qué no creas uno?"
+	},
+	"enabled": {
+		"defaultMessage": "Habilitado"
+	},
+	"error.access.at-least-one": {
+		"defaultMessage": "Se requiere al menos una Autorización o una Regla de Acceso"
+	},
+	"error.access.duplicate-usernames": {
+		"defaultMessage": "Los nombres de usuario de autorización deben ser únicos"
+	},
+	"error.invalid-auth": {
+		"defaultMessage": "Correo electrónico o contraseña no válidos"
+	},
+	"error.invalid-domain": {
+		"defaultMessage": "Dominio no válido: {domain}"
+	},
+	"error.invalid-email": {
+		"defaultMessage": "Dirección de correo electrónico no válida"
+	},
+	"error.max-character-length": {
+		"defaultMessage": "La longitud máxima es {max} caracter{max, plural, one {} other {es}}"
+	},
+	"error.max-domains": {
+		"defaultMessage": "Demasiados dominios, el máximo es {max}"
+	},
+	"error.maximum": {
+		"defaultMessage": "El máximo es {max}"
+	},
+	"error.min-character-length": {
+		"defaultMessage": "La longitud mínima es {min} caracter{min, plural, one {} other {es}}"
+	},
+	"error.minimum": {
+		"defaultMessage": "El mínimo es {min}"
+	},
+	"error.passwords-must-match": {
+		"defaultMessage": "Las contraseñas deben coincidir"
+	},
+	"error.required": {
+		"defaultMessage": "Este campo es obligatorio"
+	},
+	"expires.on": {
+		"defaultMessage": "Expira: {date}"
+	},
+	"footer.github-fork": {
+		"defaultMessage": "Bifúrcame en Github"
+	},
+	"host.flags.block-exploits": {
+		"defaultMessage": "Bloquear Exploits Comunes"
+	},
+	"host.flags.cache-assets": {
+		"defaultMessage": "Cachear Recursos"
+	},
+	"host.flags.preserve-path": {
+		"defaultMessage": "Preservar Ruta"
+	},
+	"host.flags.protocols": {
+		"defaultMessage": "Protocolos"
+	},
+	"host.flags.websockets-upgrade": {
+		"defaultMessage": "Soporte de Websockets"
+	},
+	"host.forward-port": {
+		"defaultMessage": "Puerto de Reenvío"
+	},
+	"host.forward-scheme": {
+		"defaultMessage": "Esquema"
+	},
+	"hosts": {
+		"defaultMessage": "Hosts"
+	},
+	"http-only": {
+		"defaultMessage": "Solo HTTP"
+	},
+	"lets-encrypt": {
+		"defaultMessage": "Let's Encrypt"
+	},
+	"lets-encrypt-via-dns": {
+		"defaultMessage": "Let's Encrypt vía DNS"
+	},
+	"lets-encrypt-via-http": {
+		"defaultMessage": "Let's Encrypt vía HTTP"
+	},
+	"loading": {
+		"defaultMessage": "Cargando…"
+	},
+	"login.title": {
+		"defaultMessage": "Inicia sesión en tu cuenta"
+	},
+	"nginx-config.label": {
+		"defaultMessage": "Configuración Personalizada de Nginx"
+	},
+	"nginx-config.placeholder": {
+		"defaultMessage": "# ¡Introduce aquí tu configuración personalizada de Nginx bajo tu propio riesgo!"
+	},
+	"no-permission-error": {
+		"defaultMessage": "No tienes acceso para ver esto."
+	},
+	"notfound.action": {
+		"defaultMessage": "Llévame al inicio"
+	},
+	"notfound.content": {
+		"defaultMessage": "Lo sentimos, pero la página que buscas no fue encontrada"
+	},
+	"notfound.title": {
+		"defaultMessage": "Ups… Has encontrado una página de error"
+	},
+	"notification.error": {
+		"defaultMessage": "Error"
+	},
+	"notification.object-deleted": {
+		"defaultMessage": "{object} ha sido eliminado"
+	},
+	"notification.object-disabled": {
+		"defaultMessage": "{object} ha sido deshabilitado"
+	},
+	"notification.object-enabled": {
+		"defaultMessage": "{object} ha sido habilitado"
+	},
+	"notification.object-renewed": {
+		"defaultMessage": "{object} ha sido renovado"
+	},
+	"notification.object-saved": {
+		"defaultMessage": "{object} ha sido guardado"
+	},
+	"notification.success": {
+		"defaultMessage": "Éxito"
+	},
+	"object.actions-title": {
+		"defaultMessage": "{object} #{id}"
+	},
+	"object.add": {
+		"defaultMessage": "Añadir {object}"
+	},
+	"object.delete": {
+		"defaultMessage": "Eliminar {object}"
+	},
+	"object.delete.content": {
+		"defaultMessage": "¿Estás seguro de que quieres eliminar este {object}?"
+	},
+	"object.edit": {
+		"defaultMessage": "Editar {object}"
+	},
+	"object.empty": {
+		"defaultMessage": "No hay {objects}"
+	},
+	"object.event.created": {
+		"defaultMessage": "{object} Creado"
+	},
+	"object.event.deleted": {
+		"defaultMessage": "{object} Eliminado"
+	},
+	"object.event.disabled": {
+		"defaultMessage": "{object} Deshabilitado"
+	},
+	"object.event.enabled": {
+		"defaultMessage": "{object} Habilitado"
+	},
+	"object.event.renewed": {
+		"defaultMessage": "{object} Renovado"
+	},
+	"object.event.updated": {
+		"defaultMessage": "{object} Actualizado"
+	},
+	"offline": {
+		"defaultMessage": "Desconectado"
+	},
+	"online": {
+		"defaultMessage": "Conectado"
+	},
+	"options": {
+		"defaultMessage": "Opciones"
+	},
+	"password": {
+		"defaultMessage": "Contraseña"
+	},
+	"password.generate": {
+		"defaultMessage": "Generar contraseña aleatoria"
+	},
+	"password.hide": {
+		"defaultMessage": "Ocultar Contraseña"
+	},
+	"password.show": {
+		"defaultMessage": "Mostrar Contraseña"
+	},
+	"permissions.hidden": {
+		"defaultMessage": "Oculto"
+	},
+	"permissions.manage": {
+		"defaultMessage": "Gestionar"
+	},
+	"permissions.view": {
+		"defaultMessage": "Solo Ver"
+	},
+	"permissions.visibility.all": {
+		"defaultMessage": "Todos los Elementos"
+	},
+	"permissions.visibility.title": {
+		"defaultMessage": "Visibilidad de Elementos"
+	},
+	"permissions.visibility.user": {
+		"defaultMessage": "Solo Elementos Creados"
+	},
+	"proxy-host": {
+		"defaultMessage": "Host Proxy"
+	},
+	"proxy-host.forward-host": {
+		"defaultMessage": "Nombre de Host / IP de Reenvío"
+	},
+	"proxy-hosts": {
+		"defaultMessage": "Hosts Proxy"
+	},
+	"proxy-hosts.count": {
+		"defaultMessage": "{count} {count, plural, one {Host Proxy} other {Hosts Proxy}}"
+	},
+	"public": {
+		"defaultMessage": "Público"
+	},
+	"redirection-host": {
+		"defaultMessage": "Host de Redirección"
+	},
+	"redirection-host.forward-domain": {
+		"defaultMessage": "Dominio de Reenvío"
+	},
+	"redirection-host.forward-http-code": {
+		"defaultMessage": "Código HTTP"
+	},
+	"redirection-hosts": {
+		"defaultMessage": "Hosts de Redirección"
+	},
+	"redirection-hosts.count": {
+		"defaultMessage": "{count} {count, plural, one {Host de Redirección} other {Hosts de Redirección}}"
+	},
+	"role.admin": {
+		"defaultMessage": "Administrador"
+	},
+	"role.standard-user": {
+		"defaultMessage": "Usuario Estándar"
+	},
+	"save": {
+		"defaultMessage": "Guardar"
+	},
+	"setting": {
+		"defaultMessage": "Configuración"
+	},
+	"settings": {
+		"defaultMessage": "Configuración"
+	},
+	"settings.default-site": {
+		"defaultMessage": "Sitio Predeterminado"
+	},
+	"settings.default-site.404": {
+		"defaultMessage": "Página 404"
+	},
+	"settings.default-site.444": {
+		"defaultMessage": "Sin Respuesta (444)"
+	},
+	"settings.default-site.congratulations": {
+		"defaultMessage": "Página de Felicitaciones"
+	},
+	"settings.default-site.description": {
+		"defaultMessage": "Qué mostrar cuando Nginx recibe un Host desconocido"
+	},
+	"settings.default-site.html": {
+		"defaultMessage": "HTML Personalizado"
+	},
+	"settings.default-site.html.placeholder": {
+		"defaultMessage": "<!-- Introduce aquí tu contenido HTML personalizado -->"
+	},
+	"settings.default-site.redirect": {
+		"defaultMessage": "Redirigir"
+	},
+	"setup.preamble": {
+		"defaultMessage": "Comienza creando tu cuenta de administrador."
+	},
+	"setup.title": {
+		"defaultMessage": "¡Bienvenido!"
+	},
+	"sign-in": {
+		"defaultMessage": "Iniciar Sesión"
+	},
+	"ssl-certificate": {
+		"defaultMessage": "Certificado SSL"
+	},
+	"stream": {
+		"defaultMessage": "Stream"
+	},
+	"stream.forward-host": {
+		"defaultMessage": "Host de Reenvío"
+	},
+	"stream.incoming-port": {
+		"defaultMessage": "Puerto de Entrada"
+	},
+	"streams": {
+		"defaultMessage": "Streams"
+	},
+	"streams.count": {
+		"defaultMessage": "{count} {count, plural, one {Stream} other {Streams}}"
+	},
+	"streams.tcp": {
+		"defaultMessage": "TCP"
+	},
+	"streams.udp": {
+		"defaultMessage": "UDP"
+	},
+	"test": {
+		"defaultMessage": "Probar"
+	},
+	"user": {
+		"defaultMessage": "Usuario"
+	},
+	"user.change-password": {
+		"defaultMessage": "Cambiar Contraseña"
+	},
+	"user.confirm-password": {
+		"defaultMessage": "Confirmar Contraseña"
+	},
+	"user.current-password": {
+		"defaultMessage": "Contraseña Actual"
+	},
+	"user.edit-profile": {
+		"defaultMessage": "Editar Perfil"
+	},
+	"user.full-name": {
+		"defaultMessage": "Nombre Completo"
+	},
+	"user.login-as": {
+		"defaultMessage": "Iniciar sesión como {name}"
+	},
+	"user.logout": {
+		"defaultMessage": "Cerrar Sesión"
+	},
+	"user.new-password": {
+		"defaultMessage": "Nueva Contraseña"
+	},
+	"user.nickname": {
+		"defaultMessage": "Apodo"
+	},
+	"user.set-password": {
+		"defaultMessage": "Establecer Contraseña"
+	},
+	"user.set-permissions": {
+		"defaultMessage": "Establecer Permisos para {name}"
+	},
+	"user.switch-dark": {
+		"defaultMessage": "Cambiar a modo Oscuro"
+	},
+	"user.switch-light": {
+		"defaultMessage": "Cambiar a modo Claro"
+	},
+	"username": {
+		"defaultMessage": "Nombre de Usuario"
+	},
+	"users": {
+		"defaultMessage": "Usuarios"
+	}
+}

+ 641 - 0
frontend/src/locale/src/ja.json

@@ -0,0 +1,641 @@
+{
+	"access-list": {
+		"defaultMessage": "アクセスリスト"
+	},
+	"access-list.access-count": {
+		"defaultMessage": "{count} ルール"
+	},
+	"access-list.auth-count": {
+		"defaultMessage": "{count} ユーザー"
+	},
+	"access-list.help-rules-last": {
+		"defaultMessage": "少なくとも 1 つのルールが存在する場合、 他のすべてを拒否するルールが最後に追加されます"
+	},
+	"access-list.help.rules-order": {
+		"defaultMessage": "許可コマンドと拒否コマンドは定義された順番で適用されます"
+	},
+	"access-list.pass-auth": {
+		"defaultMessage": "認証情報をアップストリームに送信する"
+	},
+	"access-list.public": {
+		"defaultMessage": "公開されたアクセス"
+	},
+	"access-list.public.subtitle": {
+		"defaultMessage": "ベーシック認証を使用しません"
+	},
+	"access-list.satisfy-any": {
+		"defaultMessage": "いずれかを満たす"
+	},
+	"access-list.subtitle": {
+		"defaultMessage": "{users} ユーザー, {rules} ルール - 作成日時: {date}"
+	},
+	"access-lists": {
+		"defaultMessage": "アクセスリスト"
+	},
+	"action.add": {
+		"defaultMessage": "追加"
+	},
+	"action.add-location": {
+		"defaultMessage": "場所を追加"
+	},
+	"action.close": {
+		"defaultMessage": "閉じる"
+	},
+	"action.delete": {
+		"defaultMessage": "削除"
+	},
+	"action.disable": {
+		"defaultMessage": "無効化"
+	},
+	"action.download": {
+		"defaultMessage": "ダウンロード"
+	},
+	"action.edit": {
+		"defaultMessage": "編集"
+	},
+	"action.enable": {
+		"defaultMessage": "有効化"
+	},
+	"action.permissions": {
+		"defaultMessage": "権限"
+	},
+	"action.renew": {
+		"defaultMessage": "更新"
+	},
+	"action.view-details": {
+		"defaultMessage": "詳細"
+	},
+	"auditlogs": {
+		"defaultMessage": "監査ログ"
+	},
+	"cancel": {
+		"defaultMessage": "キャンセル"
+	},
+	"certificate": {
+		"defaultMessage": "証明書"
+	},
+	"certificate.custom-certificate": {
+		"defaultMessage": "証明書"
+	},
+	"certificate.custom-certificate-key": {
+		"defaultMessage": "証明書キー"
+	},
+	"certificate.custom-intermediate": {
+		"defaultMessage": "中間証明書"
+	},
+	"certificate.in-use": {
+		"defaultMessage": "使用中"
+	},
+	"certificate.none.subtitle": {
+		"defaultMessage": "証明書が割り当てられていません"
+	},
+	"certificate.none.subtitle.for-http": {
+		"defaultMessage": "このホストはHTTPSを使用しません"
+	},
+	"certificate.none.title": {
+		"defaultMessage": "無し"
+	},
+	"certificate.not-in-use": {
+		"defaultMessage": "未使用"
+	},
+	"certificate.renew": {
+		"defaultMessage": "証明書を更新"
+	},
+	"certificates": {
+		"defaultMessage": "証明書"
+	},
+	"certificates.custom": {
+		"defaultMessage": "カスタム証明書"
+	},
+	"certificates.custom.warning": {
+		"defaultMessage": "パスワードによって保護されたキーファイルはサポートされていません"
+	},
+	"certificates.dns.credentials": {
+		"defaultMessage": "資格情報ファイルの内容"
+	},
+	"certificates.dns.credentials-note": {
+		"defaultMessage": "このプラグインはプロバイダーのAPIキーか認証情報を含む設定ファイルが必要です"
+	},
+	"certificates.dns.credentials-warning": {
+		"defaultMessage": "このデータはファイルとデータベースにプレーンテキストとして保存されます"
+	},
+	"certificates.dns.propagation-seconds": {
+		"defaultMessage": "DNS伝播時間(秒)"
+	},
+	"certificates.dns.propagation-seconds-note": {
+		"defaultMessage": "DNSの伝搬時間を秒で指定します。空にするとデフォルトの値を使用します。"
+	},
+	"certificates.dns.provider": {
+		"defaultMessage": "DNSプロバイダー"
+	},
+	"certificates.dns.warning": {
+		"defaultMessage": "このセクションはCertbotとそのDNSプラグインの知識が必要です。各プラグインのドキュメントを参照してください。"
+	},
+	"certificates.http.reachability-404": {
+		"defaultMessage": "このドメインはNginx Proxy Managerではないサーバーを指しているようです。ドメインがこのNPMインスタンスを指していることを確認してください。"
+	},
+	"certificates.http.reachability-failed-to-check": {
+		"defaultMessage": "site24x7.comへの接続でエラーが発生し、到達性チェックに失敗しました"
+	},
+	"certificates.http.reachability-not-resolved": {
+		"defaultMessage": "このドメインには利用可能なサーバーがありません。ドメインが存在し、NPMインスタンスのIPアドレスを指していること、必要に応じてルーターでポート80が転送されていることを確認してください。"
+	},
+	"certificates.http.reachability-ok": {
+		"defaultMessage": "サーバーへ到達可能であり、証明書の作成が可能です。"
+	},
+	"certificates.http.reachability-other": {
+		"defaultMessage": "このドメインでサーバーが見つかりましたが予期しないステータスコード {code} を返しました. NPMサーバーが動いていますか? ドメインがこのNPMインスタンスを指していることを確認してください。"
+	},
+	"certificates.http.reachability-wrong-data": {
+		"defaultMessage": "このドメインでサーバーが見つかりましたが予期しないデータを返しました. NPMサーバーが動いていますか? ドメインがこのNPMインスタンスを指していることを確認してください。"
+	},
+	"certificates.http.test-results": {
+		"defaultMessage": "テスト結果"
+	},
+	"certificates.http.warning": {
+		"defaultMessage": "これらのドメインは、すでにこのインストール先を指すように設定されている必要がありますあ."
+	},
+	"certificates.request.subtitle": {
+		"defaultMessage": "Let's Encryptを使用する"
+	},
+	"certificates.request.title": {
+		"defaultMessage": "新しい証明書を作成"
+	},
+	"column.access": {
+		"defaultMessage": "アクセス"
+	},
+	"column.authorization": {
+		"defaultMessage": "認証"
+	},
+	"column.authorizations": {
+		"defaultMessage": "認証"
+	},
+	"column.custom-locations": {
+		"defaultMessage": "カスタムロケーション"
+	},
+	"column.destination": {
+		"defaultMessage": "宛先"
+	},
+	"column.details": {
+		"defaultMessage": "詳細"
+	},
+	"column.email": {
+		"defaultMessage": "Email"
+	},
+	"column.event": {
+		"defaultMessage": "イベント"
+	},
+	"column.expires": {
+		"defaultMessage": "期限切れ"
+	},
+	"column.http-code": {
+		"defaultMessage": "アクセス"
+	},
+	"column.incoming-port": {
+		"defaultMessage": "受信ポート"
+	},
+	"column.name": {
+		"defaultMessage": "名前"
+	},
+	"column.protocol": {
+		"defaultMessage": "プロトコル"
+	},
+	"column.provider": {
+		"defaultMessage": "プロバイダー"
+	},
+	"column.roles": {
+		"defaultMessage": "Roles"
+	},
+	"column.rules": {
+		"defaultMessage": "ルール"
+	},
+	"column.satisfy": {
+		"defaultMessage": "Satisfy"
+	},
+	"column.satisfy-all": {
+		"defaultMessage": "すべて"
+	},
+	"column.satisfy-any": {
+		"defaultMessage": "いずれか"
+	},
+	"column.scheme": {
+		"defaultMessage": "スキーム"
+	},
+	"column.source": {
+		"defaultMessage": "ソース"
+	},
+	"column.ssl": {
+		"defaultMessage": "SSL"
+	},
+	"column.status": {
+		"defaultMessage": "ステータス"
+	},
+	"created-on": {
+		"defaultMessage": "作成日時: {date}"
+	},
+	"dashboard": {
+		"defaultMessage": "ダッシュボード"
+	},
+	"dead-host": {
+		"defaultMessage": "404 ホスト"
+	},
+	"dead-hosts": {
+		"defaultMessage": "404 ホスト"
+	},
+	"dead-hosts.count": {
+		"defaultMessage": "{count} 404 ホスト"
+	},
+	"disabled": {
+		"defaultMessage": "無効化"
+	},
+	"domain-names": {
+		"defaultMessage": "ドメイン名"
+	},
+	"domain-names.max": {
+		"defaultMessage": "{count}のドメイン名が最大です"
+	},
+	"domain-names.placeholder": {
+		"defaultMessage": "追加するドメインを入力..."
+	},
+	"domain-names.wildcards-not-permitted": {
+		"defaultMessage": "ワイルドカードはこのタイプでは許可されていません"
+	},
+	"domain-names.wildcards-not-supported": {
+		"defaultMessage": "ワイルドカードはこのCAではサポートされていません"
+	},
+	"domains.force-ssl": {
+		"defaultMessage": "SSLを強制"
+	},
+	"domains.hsts-enabled": {
+		"defaultMessage": "HSTSを有効化"
+	},
+	"domains.hsts-subdomains": {
+		"defaultMessage": "HSTSサブドメイン"
+	},
+	"domains.http2-support": {
+		"defaultMessage": "HTTP/2サポート"
+	},
+	"domains.use-dns": {
+		"defaultMessage": "DNSチャレンジを使用"
+	},
+	"email-address": {
+		"defaultMessage": "Emailアドレス"
+	},
+	"empty-search": {
+		"defaultMessage": "見つかりませんでした"
+	},
+	"empty-subtitle": {
+		"defaultMessage": "作ってみましょう"
+	},
+	"enabled": {
+		"defaultMessage": "有効"
+	},
+	"error.access.at-least-one": {
+		"defaultMessage": "少なくとも一つの認証またはアクセスルールが必要です"
+	},
+	"error.access.duplicate-usernames": {
+		"defaultMessage": "認証のユーザー名は他と同じ名前は使用できません"
+	},
+	"error.invalid-auth": {
+		"defaultMessage": "無効なemailまたはパスワード"
+	},
+	"error.invalid-domain": {
+		"defaultMessage": "無効なドメイン: {domain}"
+	},
+	"error.invalid-email": {
+		"defaultMessage": "無効なemailアドレス"
+	},
+	"error.max-character-length": {
+		"defaultMessage": "文字数は長くとも{max}文字です"
+	},
+	"error.max-domains": {
+		"defaultMessage": "ドメインが多すぎます, 最大値は{max}です"
+	},
+	"error.maximum": {
+		"defaultMessage": "最大値は{max}です"
+	},
+	"error.min-character-length": {
+		"defaultMessage": "文字数は少なくとも{min}文字です"
+	},
+	"error.minimum": {
+		"defaultMessage": "最小値は{min}です"
+	},
+	"error.passwords-must-match": {
+		"defaultMessage": "パスワードは一致する必要があります"
+	},
+	"error.required": {
+		"defaultMessage": "必須項目です"
+	},
+	"expires.on": {
+		"defaultMessage": "有効期限: {date}"
+	},
+	"footer.github-fork": {
+		"defaultMessage": "Fork me on Github"
+	},
+	"host.flags.block-exploits": {
+		"defaultMessage": "一般的なエクスプロイトをブロックする"
+	},
+	"host.flags.cache-assets": {
+		"defaultMessage": "アセットをキャッシュする"
+	},
+	"host.flags.preserve-path": {
+		"defaultMessage": "パスワードは一致する必要があります"
+	},
+	"host.flags.protocols": {
+		"defaultMessage": "プロトコル"
+	},
+	"host.flags.websockets-upgrade": {
+		"defaultMessage": "Websocketsサポート"
+	},
+	"host.forward-port": {
+		"defaultMessage": "転送ポート"
+	},
+	"host.forward-scheme": {
+		"defaultMessage": "スキーム"
+	},
+	"hosts": {
+		"defaultMessage": "ホスト"
+	},
+	"http-only": {
+		"defaultMessage": "HTTP Only"
+	},
+	"lets-encrypt": {
+		"defaultMessage": "Let's Encrypt"
+	},
+	"lets-encrypt-via-dns": {
+		"defaultMessage": "Let's Encrypt via DNS"
+	},
+	"lets-encrypt-via-http": {
+		"defaultMessage": "Let's Encrypt via HTTP"
+	},
+	"loading": {
+		"defaultMessage": "Loading…"
+	},
+	"login.title": {
+		"defaultMessage": "アカウントにログイン"
+	},
+	"nginx-config.label": {
+		"defaultMessage": "カスタムNginx設定"
+	},
+	"nginx-config.placeholder": {
+		"defaultMessage": "# Enter your custom Nginx configuration here at your own risk!"
+	},
+	"no-permission-error": {
+		"defaultMessage": "これを表示する権限がありません"
+	},
+	"notfound.action": {
+		"defaultMessage": "ホームに戻る"
+	},
+	"notfound.content": {
+		"defaultMessage": "申し訳ありませんが探しているページは見つかりませんでした"
+	},
+	"notfound.title": {
+		"defaultMessage": "おっと... エラーページにたどり着いてしまったようです"
+	},
+	"notification.error": {
+		"defaultMessage": "エラー"
+	},
+	"notification.object-deleted": {
+		"defaultMessage": "{object}は削除されました"
+	},
+	"notification.object-disabled": {
+		"defaultMessage": "{object}は無効化されました"
+	},
+	"notification.object-enabled": {
+		"defaultMessage": "{object}は有効化されました"
+	},
+	"notification.object-renewed": {
+		"defaultMessage": "{object}は再作成されました"
+	},
+	"notification.object-saved": {
+		"defaultMessage": "{object}は保存されました"
+	},
+	"notification.success": {
+		"defaultMessage": "成功"
+	},
+	"object.actions-title": {
+		"defaultMessage": "{object} #{id}"
+	},
+	"object.add": {
+		"defaultMessage": "{object}を追加"
+	},
+	"object.delete": {
+		"defaultMessage": "{object}を削除"
+	},
+	"object.delete.content": {
+		"defaultMessage": "本当に{object}を削除しますか?"
+	},
+	"object.edit": {
+		"defaultMessage": "{object}を編集"
+	},
+	"object.empty": {
+		"defaultMessage": "{objects}はありません"
+	},
+	"object.event.created": {
+		"defaultMessage": "{object}を作成済み"
+	},
+	"object.event.deleted": {
+		"defaultMessage": "{object}を削除済み"
+	},
+	"object.event.disabled": {
+		"defaultMessage": "{object}を無効化済み"
+	},
+	"object.event.enabled": {
+		"defaultMessage": "{object}を有効化済み"
+	},
+	"object.event.renewed": {
+		"defaultMessage": "{object}を再作成済み"
+	},
+	"object.event.updated": {
+		"defaultMessage": "{object}を更新済み"
+	},
+	"offline": {
+		"defaultMessage": "Offline"
+	},
+	"online": {
+		"defaultMessage": "Online"
+	},
+	"options": {
+		"defaultMessage": "Options"
+	},
+	"password": {
+		"defaultMessage": "パスワード"
+	},
+	"password.generate": {
+		"defaultMessage": "ランダムなパスワードを生成"
+	},
+	"password.hide": {
+		"defaultMessage": "パスワードを隠す"
+	},
+	"password.show": {
+		"defaultMessage": "パスワードを表示する"
+	},
+	"permissions.hidden": {
+		"defaultMessage": "非公開"
+	},
+	"permissions.manage": {
+		"defaultMessage": "管理"
+	},
+	"permissions.view": {
+		"defaultMessage": "表示のみ"
+	},
+	"permissions.visibility.all": {
+		"defaultMessage": "すべて"
+	},
+	"permissions.visibility.title": {
+		"defaultMessage": "可視性"
+	},
+	"permissions.visibility.user": {
+		"defaultMessage": "作成したもののみ"
+	},
+	"proxy-host": {
+		"defaultMessage": "プロキシホスト"
+	},
+	"proxy-host.forward-host": {
+		"defaultMessage": "転送ホスト名/IP"
+	},
+	"proxy-hosts": {
+		"defaultMessage": "プロキシホスト"
+	},
+	"proxy-hosts.count": {
+		"defaultMessage": "{count} プロキシホスト"
+	},
+	"public": {
+		"defaultMessage": "Public"
+	},
+	"redirection-host": {
+		"defaultMessage": "リダイレクトホスト"
+	},
+	"redirection-host.forward-domain": {
+		"defaultMessage": "転送ホスト"
+	},
+	"redirection-hosts": {
+		"defaultMessage": "リダイレクトホスト"
+	},
+	"redirection-hosts.count": {
+		"defaultMessage": "{count} リダイレクトホスト"
+	},
+	"role.admin": {
+		"defaultMessage": "管理者"
+	},
+	"role.standard-user": {
+		"defaultMessage": "一般ユーザー"
+	},
+	"save": {
+		"defaultMessage": "保存"
+	},
+	"setting": {
+		"defaultMessage": "設定"
+	},
+	"settings": {
+		"defaultMessage": "設定"
+	},
+	"settings.default-site": {
+		"defaultMessage": "デフォルトサイト"
+	},
+	"settings.default-site.404": {
+		"defaultMessage": "404ページ"
+	},
+	"settings.default-site.444": {
+		"defaultMessage": "返答しない (444)"
+	},
+	"settings.default-site.congratulations": {
+		"defaultMessage": "設定ページ"
+	},
+	"settings.default-site.description": {
+		"defaultMessage": "不明なホストを要求されたときにNginxが何を返すかを設定します"
+	},
+	"settings.default-site.html": {
+		"defaultMessage": "カスタムHTML"
+	},
+	"settings.default-site.html.placeholder": {
+		"defaultMessage": "<!-- Enter your custom HTML content here -->"
+	},
+	"settings.default-site.redirect": {
+		"defaultMessage": "リダイレクト"
+	},
+	"setup.preamble": {
+		"defaultMessage": "管理者アカウントを作成して始めましょう"
+	},
+	"setup.title": {
+		"defaultMessage": "ようこそ!"
+	},
+	"sign-in": {
+		"defaultMessage": "サインイン"
+	},
+	"ssl-certificate": {
+		"defaultMessage": "SSL証明書"
+	},
+	"stream": {
+		"defaultMessage": "ストリーム"
+	},
+	"stream.forward-host": {
+		"defaultMessage": "転送ポート"
+	},
+	"stream.incoming-port": {
+		"defaultMessage": "受信ポート"
+	},
+	"streams": {
+		"defaultMessage": "ストリーム"
+	},
+	"streams.count": {
+		"defaultMessage": "{count} ストリーム"
+	},
+	"streams.tcp": {
+		"defaultMessage": "TCP"
+	},
+	"streams.udp": {
+		"defaultMessage": "UDP"
+	},
+	"test": {
+		"defaultMessage": "テスト"
+	},
+	"user": {
+		"defaultMessage": "ユーザー"
+	},
+	"user.change-password": {
+		"defaultMessage": "変更するパスワード"
+	},
+	"user.confirm-password": {
+		"defaultMessage": "変更するパスワードを確認"
+	},
+	"user.current-password": {
+		"defaultMessage": "現在のパスワード"
+	},
+	"user.edit-profile": {
+		"defaultMessage": "プロフィールを編集"
+	},
+	"user.full-name": {
+		"defaultMessage": "フルネーム"
+	},
+	"user.login-as": {
+		"defaultMessage": "{name}としてサインイン"
+	},
+	"user.logout": {
+		"defaultMessage": "ログアウト"
+	},
+	"user.new-password": {
+		"defaultMessage": "新しいパスワード"
+	},
+	"user.nickname": {
+		"defaultMessage": "ニックネーム"
+	},
+	"user.set-password": {
+		"defaultMessage": "パスワードを設定"
+	},
+	"user.set-permissions": {
+		"defaultMessage": "{name}に権限を設定"
+	},
+	"user.switch-dark": {
+		"defaultMessage": "ダークモードに変更"
+	},
+	"user.switch-light": {
+		"defaultMessage": "ライトモードに変更"
+	},
+	"username": {
+		"defaultMessage": "ユーザー名"
+	},
+	"users": {
+		"defaultMessage": "ユーザー"
+	}
+}

+ 9 - 0
frontend/src/locale/src/lang-list.json

@@ -1,5 +1,14 @@
 {
 	"locale-en-US": {
 		"defaultMessage": "English"
+	},
+	"locale-es-ES": {
+		"defaultMessage": "Español"
+	},
+	"locale-de-DE": {
+		"defaultMessage": "German"
+	},
+	"locale-ja-JP": {
+		"defaultMessage": "日本語"
 	}
 }

+ 1 - 1
frontend/src/modals/CustomCertificateModal.tsx

@@ -74,7 +74,7 @@ const CustomCertificateModal = EasyModal.create(({ visible, remove }: InnerModal
 					<Form>
 						<Modal.Header closeButton>
 							<Modal.Title>
-								<T id="object.add" tData={{ object: "lets-encrypt-via-dns" }} />
+								<T id="object.add" tData={{ object: "certificates.custom" }} />
 							</Modal.Title>
 						</Modal.Header>
 						<Modal.Body className="p-0">

+ 31 - 1
frontend/src/modals/RedirectionHostModal.tsx

@@ -162,7 +162,7 @@ const RedirectionHostModal = EasyModal.create(({ id, visible, remove }: Props) =
 																		required
 																		{...field}
 																	>
-																		<option value="$scheme">Auto</option>
+																		<option value="auto">Auto</option>
 																		<option value="http">http</option>
 																		<option value="https">https</option>
 																	</select>
@@ -212,6 +212,36 @@ const RedirectionHostModal = EasyModal.create(({ id, visible, remove }: Props) =
 														</Field>
 													</div>
 												</div>
+												<Field name="forwardHttpCode">
+													{({ field, form }: any) => (
+														<div className="mb-3">
+															<label className="form-label" htmlFor="forwardHttpCode">
+																<T id="redirection-host.forward-http-code" />
+															</label>
+															<select
+																id="forwardHttpCode"
+																className={`form-control ${form.errors.forwardHttpCode && form.touched.forwardHttpCode ? "is-invalid" : ""}`}
+																required
+																{...field}
+															>
+																<option value="300">300 Multiple choices</option>
+																<option value="301">301 Moved permanently</option>
+																<option value="302">302 Moved temporarily</option>
+																<option value="303">303 See other</option>
+																<option value="307">307 Temporary redirect</option>
+																<option value="308">308 Permanent redirect</option>
+															</select>
+															{form.errors.forwardHttpCode ? (
+																<div className="invalid-feedback">
+																	{form.errors.forwardHttpCode &&
+																	form.touched.forwardHttpCode
+																		? form.errors.forwardHttpCode
+																		: null}
+																</div>
+															) : null}
+														</div>
+													)}
+												</Field>
 												<div className="my-3">
 													<h4 className="py-2">
 														<T id="options" />

+ 1 - 1
frontend/src/modules/Validations.tsx

@@ -44,7 +44,7 @@ const validateEmail = () => {
 		if (!value.length) {
 			return intl.formatMessage({ id: "error.required" });
 		}
-		if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(value)) {
+		if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+$/i.test(value)) {
 			return intl.formatMessage({ id: "error.invalid-email" });
 		}
 	};