From 071692ab54caa1710d32d352a877a5e739dd6ba7 Mon Sep 17 00:00:00 2001 From: Zoey Date: Sun, 3 Nov 2024 21:56:56 +0100 Subject: [PATCH] dep updates/fix updating streams/close #965/env option to disable must-taple Signed-off-by: Zoey close #965 by merging https://github.com/NginxProxyManager/nginx-proxy-manager/pull/4166/files and adding multi lang support Co-Authored-By: Remco Kersten <55450744+kerstenremco@users.noreply.github.com> --- Dockerfile | 11 +- README.md | 96 ++-- backend/internal/certificate.js | 2 +- backend/internal/token.js | 6 +- backend/package.json | 10 +- .../paths/nginx/streams/streamID/put.json | 55 +- compose.crowdsec.yaml | 2 +- compose.geoip.yaml | 2 +- compose.yaml | 6 +- frontend/js/app/nginx/access/list/item.ejs | 4 +- .../js/app/nginx/certificates/list/item.ejs | 4 +- frontend/js/app/nginx/dead/list/item.ejs | 4 +- frontend/js/app/nginx/proxy/list/item.ejs | 4 +- .../js/app/nginx/redirection/list/item.ejs | 4 +- frontend/js/app/nginx/stream/list/item.ejs | 4 +- frontend/js/i18n/de-lang.json | 482 +++++++++--------- frontend/js/i18n/en-lang.json | 482 +++++++++--------- frontend/package.json | 2 +- rootfs/etc/certbot.ini | 1 - rootfs/usr/local/bin/start.sh | 42 +- 20 files changed, 595 insertions(+), 628 deletions(-) diff --git a/Dockerfile b/Dockerfile index 795a89b09..2add08e9b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -71,15 +71,12 @@ RUN apk upgrade --no-cache -a && \ sed -i "s|APPSEC_PROCESS_TIMEOUT=.*|APPSEC_PROCESS_TIMEOUT=10000|g" /src/crowdsec-nginx-bouncer/lua-mod/config_example.conf -FROM zoeyvid/nginx-quic:351-python +FROM zoeyvid/nginx-quic:352-python SHELL ["/bin/ash", "-eo", "pipefail", "-c"] -# until https://github.com/certbot/certbot/issues/9967 is closed -ENV PYTHONWARNINGS=ignore - COPY rootfs / -COPY --from=zoeyvid/certbot-docker:60 /usr/local /usr/local -COPY --from=zoeyvid/curl-quic:423 /usr/local/bin/curl /usr/local/bin/curl +COPY --from=zoeyvid/certbot-docker:64 /usr/local /usr/local +COPY --from=zoeyvid/curl-quic:426 /usr/local/bin/curl /usr/local/bin/curl COPY --from=strip-backend /app /app COPY --from=frontend /app/dist /html/frontend @@ -125,6 +122,8 @@ ENV NODE_ENV=production \ DB_SQLITE_FILE=/data/etc/npm/database.sqlite ENV ACME_SERVER="https://acme-v02.api.letsencrypt.org/directory" \ + ACME_MUST_STAPLE=true \ + ACME_SERVER_TLS_VERIFY=true \ PUID=0 \ PGID=0 \ NIBEP=48693 \ diff --git a/README.md b/README.md index b4be69951..eaa2161ec 100644 --- a/README.md +++ b/README.md @@ -4,23 +4,16 @@ This project comes as a pre-built docker image that enables you to easily forwar running at home or otherwise, including free TLS, without having to know too much about Nginx or Certbot. - [Quick Setup](#quick-setup) - - - -**Note: Reloading the NPMplus UI can cause a 502 error. See https://github.com/ZoeyVid/NPMplus/issues/241.**
+ **Note: NO armv7, route53 and aws cloudfront ip ranges support.**
-**Note: add `net.ipv4.ip_unprivileged_port_start=0` at the end of `/etc/sysctl.conf` to support PUID/PGID in network mode host.**
-**Note: If you don't use network mode host, which I don't recommend, don't forget to expose port 443 on tcp AND udp (http3/quic needs udp).**
-**Note: If you don't use network mode host, which I don't recommend, don't forget to enable IPv6 in Docker, see [here](https://github.com/nextcloud/all-in-one/blob/main/docker-ipv6-support.md), you only need to follow step one and two before deploying NPMplus!**
-**Note: Don't forget to open Port 80 (tcp) and 443 (tcp AND udp, http3/quic needs udp) in your firewall (because of network mode host, you also need to open this ports in ufw, if you use ufw).**
-**Note: ModSecurity overblocking (403 Error)? Please see `/opt/npm/etc/modsecurity`, if you also use CRS please see [here](https://coreruleset.org/docs/concepts/false_positives_tuning).**
**Note: Other Databases like MariaDB may work, but are unsupported.**
+**Note: watchtower does NOT update NPMplus, you need to do it yourself (it will only pull the image, but not update the container itself).**
**Note: access.log/stream.log, logrotate and goaccess are NOT enabled by default bceuase of GDPR, you can enable them in the compose.yaml.**
+**Note: add `net.ipv4.ip_unprivileged_port_start=0` at the end of `/etc/sysctl.conf` to support PUID/PGID in network mode host.**
+**Note: Don't forget to open Port 80 (tcp) and 443 (tcp AND udp, http3/quic needs udp) in your firewall (because of network mode host, you also need to open this ports in ufw, if you use ufw).**
+**Note: If you don't use network mode host, which I don't recommend, don't forget to also expose port 443/udp (http3/quic needs udp), to enable IPv6 in Docker see step 1 and 2 [here](https://github.com/nextcloud/all-in-one/blob/main/docker-ipv6-support.md).**
+ ## Project Goal I created this project to fill a personal need to provide users with an easy way to accomplish reverse @@ -28,12 +21,6 @@ proxying hosts with TLS termination and it had to be so easy that a monkey could While there might be advanced options they are optional and the project should be as simple as possible so that the barrier for entry here is low. - - - ## Features - Beautiful and Secure Admin Interface based on [Tabler](https://tabler.github.io) @@ -49,23 +36,23 @@ so that the barrier for entry here is low. - Supports HTTP/3 (QUIC) protocol. - Supports CrowdSec IPS. Please see [here](https://github.com/ZoeyVid/NPMplus#crowdsec) to enable it. - goaccess included, see compose.yaml to enable, runs by default on https://:91 (nginx config from [here](https://github.com/xavier-hernandez/goaccess-for-nginxproxymanager/blob/main/resources/nginx/nginx.conf)) -- Supports ModSecurity, with coreruleset as an option. You can configure ModSecurity/coreruleset by editing the files in the `/opt/npm/etc/modsecurity` folder. - - If the core ruleset blocks valid requests, please check the `/opt/npm/etc/modsecurity/crs-setup.conf` file. +- Supports ModSecurity, with coreruleset as an option. You can configure ModSecurity/coreruleset by editing the files in the `/opt/npm/etc/modsecurity` folder (no support from me, you need to write the rules yourself - for CRS I can try to help you). + - ModSecurity by default blocks uploads of big files, you need to edit its config to fix this, but it can use a lot of resources to scan big files by ModSecurity + - ModSecurity overblocking (403 Error) with CRS? Please see [here](https://coreruleset.org/docs/concepts/false_positives_tuning) and edit the `/opt/npm/etc/modsecurity/crs-setup.conf` file. - Try to whitelist the Content-Type you are sending (for example, `application/activity+json` for Mastodon and `application/dns-message` for DoH). - Try to whitelist the HTTP request method you are using (for example, `PUT` is blocked by default, which also affects NPM). - + - CRS plugins are supported, you can find a guide in this readme - Darkmode button in the footer for comfortable viewing (CSS done by [@theraw](https://github.com/theraw)) - Fixes proxy to https origin when the origin only accepts TLSv1.3 -- Only enables TLSv1.2 and TLSv1.3 protocols -- Faster creation of TLS certificates can be achieved by eliminating unnecessary Nginx reloads and configuration creations. -- Uses OCSP Stapling for enhanced security +- Only enables TLSv1.2 and TLSv1.3 protocols, also ML-KEM support +- Faster creation of TLS certificates is achieved by eliminating unnecessary nginx reloads and configuration creations. +- Uses OCSP Stapling for enhanced security (manual certs not supported) - Resolved dnspod plugin issue - To migrate manually, delete all dnspod certs and recreate them OR change the credentials file as per the template given [here](https://github.com/ZoeyVid/NPMplus/blob/develop/global/certbot-dns-plugins.js) - Smaller docker image with alpine-based distribution - Admin backend interface runs with https - Default page also runs with https +- option to change default TLS cert - Uses [fancyindex](https://gitHub.com/Naereen/Nginx-Fancyindex-Theme) if used as webserver - Exposes INTERNAL backend api only to localhost - Basic security headers are added if you enable HSTS (HSTS has always subdomains and preload enabled) @@ -73,28 +60,28 @@ so that the barrier for entry here is low. - Error Log written to console - `Server` response header hidden - PHP 8.2/8.3 optional, with option to add extensions; available packages can added using envs in the compose file -- Allows different acme servers/certbot config file (/opt/npm/tls/certbot/config.ini) +- Allows different acme servers using env - Supports up to 99 domains per cert - Brotli compression can be enabled - HTTP/2 always enabled with fixed upload -- Allows infinite upload size +- Allows infinite upload size (may be limited if you use ModSecurity) - Automatic database vacuum (only sqlite) -- Automatic cleaning of old certbot certs (set FULLCLEAN to true) +- Automatic cleaning of old invalid certbot certs (set CLEAN to true) - Password reset (only sqlite) using `docker exec -it npmplus password-reset.js USER_EMAIL PASSWORD` - Supports TLS for MariaDB/MySQL; set `DB_MYSQL_TLS` env to true. Self-signed certificates can be uploaded to `/opt/npm/etc/npm/ca.crt` and `DB_MYSQL_CA` set to `/data/etc/npm/ca.crt` (not tested, unsupported) -- Supports PUID/PGID in network mode host; add `net.ipv4.ip_unprivileged_port_start=0` at the end of `/etc/sysctl.conf` -- Option to set IP bindings for multiple instances in network mode host -- Option to change backend port -- multi lang support, if you want to add an language, see this commit as an example: https://github.com/ZoeyVid/NPMplus/commit/a026b42329f66b89fe1fbe5e6034df5d3fc2e11f -- See the composefile for all available options -- If you want to redirect all HTTP traffic to HTTPS, you can use the `compose.override.yaml` file. +- multi lang support, if you want to add an language, see this commit as an example: https://github.com/ZoeyVid/NPMplus/commit/a026b42329f66b89fe1fbe5e6034df5d3fc2e11f (implementation based on [@lateautumn233](https://github.com/lateautumn233) fork) +- See the compose file for all available options +- many env options optimized for network_mode host (ports/ip bindings) +- allow port range in streams +- fixed smaller issues/bugs +- other small changes/improvements ## migration - **NOTE: migrating back to the original is not possible**, so make first a **backup** before migration, so you can use the backup to switch back - please delete all dnspod certs and recreate them after migration OR you manually change the credentialsfile (see [here](https://github.com/ZoeyVid/npmplus/blob/develop/global/certbot-dns-plugins.json) for the template) - stop nginx-proxy-manager download the latest compose.yaml, adjust your paths (of /etc/letsencrypt and /data) to the ones you used with nginx-proxy-manager and adjust the env of the compose file how you like it and then deploy it - you can now remove the /etc/letsencrypt mount, since it was moved to /data while migration and redeploy the compose file -- since this fork has dependency on `network_mode: host`, please don't forget to open port 80/tcp, 443/tcp and 443/udp (and maybe 81/tcp) in your firewall +- since this fork uses `network_mode: host` by default (and all guides are written for this mode), please don't forget to open port 80/tcp, 443/tcp and 443/udp (and maybe 81/tcp) in your firewall - since many buttons changed, please edit every host you have and click save. (Please also resave it, if all buttons/values are fine, to update the host config to fully fit the NPMplus template) - maybe setup crowdsec (see below) - please report all (migration) issues you may have @@ -123,8 +110,10 @@ Password: iArhP1j7p1P6TA92FA2FMbbUGYqwcYzxC4AVEe12Wbi94FY9gNN62aKyF1shrvG4NycjjX Immediately after logging in with this default user you will be asked to modify your details and change your password. # Crowdsec -1. Install crowdsec using this compose file: https://github.com/ZoeyVid/NPMplus/blob/develop/compose.crowdsec.yaml and enable LOGROTATE in the NPMplus compose file -2. open `/opt/crowdsec/conf/acquis.d/npmplus.yaml` and fill it with: +Note: Using Immich behind NPMplus with enabled appsec causes issues, see here: [#1241](https://github.com/ZoeyVid/NPMplus/discussions/1241) +1. set LOGROTATE to `true` in your `compose.yaml` and redeploy +2. Install crowdsec using this compose file: https://github.com/ZoeyVid/NPMplus/blob/develop/compose.crowdsec.yaml and set the timezone for it +3. open `/opt/crowdsec/conf/acquis.d/npmplus.yaml` and fill it with: ```yaml filenames: - /opt/npm/nginx/access.log @@ -150,13 +139,12 @@ source: appsec labels: type: appsec ``` -3. make sure to use `network_mode: host` in your compose file -4. run `docker exec crowdsec cscli bouncers add npmplus -o raw` and save the output -5. open `/opt/npm/etc/crowdsec/crowdsec.conf` -6. set `ENABLED` to `true` -7. use the output of step 5 as `API_KEY` -8. save the file -9. set LOGROTATE to `true` in your `compose.yaml` +4. make sure to use `network_mode: host` in your compose file +5. run `docker exec crowdsec cscli bouncers add npmplus -o raw` and save the output +6. open `/opt/npm/etc/crowdsec/crowdsec.conf` +7. set `ENABLED` to `true` +8. use the output of step 5 as `API_KEY` +9. save the file 10. redeploy the `compose.yaml` # coreruleset plugins @@ -206,16 +194,10 @@ if you need to run scripts before NPMplus launches put them under: `/opt/npm/etc you need to create this folder yourself - **NOTE:** I won't help you creating those patches/scripts if you need them you also need to know how to create them ## Contributing -All are welcome to create pull requests for this project, against the `develop` branch. -CI is used in this project. All PR's must pass before being considered. After passing, -docker builds for PR's are available on ghcr for manual verifications. - -## Contributors/Sponsor upstream NPM -Special thanks to [all of our contributors](https://github.com/NginxProxyManager/nginx-proxy-manager/graphs/contributors). -If you want to sponsor them, please see [here](https://github.com/NginxProxyManager/nginx-proxy-manager/blob/master/README.md). +All are welcome to create pull requests for this project. # Please report Bugs first to this fork before reporting them to the upstream Repository -## Getting Support -1. [Found a bug?](https://github.com/ZoeyVid/NPMplus/issues) -2. [Discussions](https://github.com/ZoeyVid/NPMplus/discussions) -3. [Reddit](https://reddit.com/r/NPMplus) +## Getting Help +1. [Support/Questions](https://github.com/ZoeyVid/NPMplus/discussions) +2. [Reddit](https://reddit.com/r/NPMplus) +3. [Bugs](https://github.com/ZoeyVid/NPMplus/issues) diff --git a/backend/internal/certificate.js b/backend/internal/certificate.js index 58d56a4d4..491bfd0c5 100644 --- a/backend/internal/certificate.js +++ b/backend/internal/certificate.js @@ -16,7 +16,7 @@ const internalAuditLog = require('./audit-log'); const internalNginx = require('./nginx'); const certbotCommand = 'certbot'; -const certbotArgs = ['--logs-dir', '/tmp/certbot-log', '--work-dir', '/tmp/certbot-work', '--config-dir', '/data/tls/certbot', '--config', '/etc/certbot.ini', '--agree-tos', '--non-interactive', '--no-eff-email', '--register-unsafely-without-email']; +const certbotArgs = ['--logs-dir', '/tmp/certbot-log', '--work-dir', '/tmp/certbot-work', '--config-dir', '/data/tls/certbot', '--config', '/etc/certbot.ini', '--agree-tos', '--non-interactive', '--no-eff-email', '--register-unsafely-without-email', process.env.ACME_MUST_STAPLE == 'false' ? '' : '--must-staple', process.env.ACME_SERVER_TLS_VERIFY == 'false' ? '--no-verify-ssl' : '']; function omissions() { return ['is_deleted', 'owner.is_deleted']; diff --git a/backend/internal/token.js b/backend/internal/token.js index 003943700..6f252632b 100644 --- a/backend/internal/token.js +++ b/backend/internal/token.js @@ -65,15 +65,15 @@ module.exports = { }; }); } else { - throw new error.AuthError('Invalid password'); + throw new error.AuthError('Invalid email or password'); } }); } else { - throw new error.AuthError('No password auth for user'); + throw new error.AuthError('Invalid email or password'); } }); } else { - throw new error.AuthError('No relevant user found'); + throw new error.AuthError('Invalid email or password'); } }); }, diff --git a/backend/package.json b/backend/package.json index 927b94a5b..12ce65e95 100644 --- a/backend/package.json +++ b/backend/package.json @@ -18,10 +18,10 @@ "gravatar": "1.8.2", "jsonwebtoken": "9.0.2", "knex": "3.1.0", - "liquidjs": "10.18.0", + "liquidjs": "10.19.0", "lodash": "4.17.21", "moment": "2.30.1", - "mysql2": "3.11.3", + "mysql2": "3.11.4", "node-rsa": "1.1.1", "objection": "3.1.5", "path": "0.12.7", @@ -31,11 +31,11 @@ "license": "MIT", "devDependencies": { "@apidevtools/swagger-parser": "10.1.0", - "@eslint/js": "9.14.0", - "eslint": "9.14.0", + "@eslint/js": "9.15.0", + "eslint": "9.15.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-prettier": "5.2.1", - "globals": "15.11.0", + "globals": "15.12.0", "prettier": "3.3.3" }, "scripts": { diff --git a/backend/schema/paths/nginx/streams/streamID/put.json b/backend/schema/paths/nginx/streams/streamID/put.json index fbfdc901b..394b3bd37 100644 --- a/backend/schema/paths/nginx/streams/streamID/put.json +++ b/backend/schema/paths/nginx/streams/streamID/put.json @@ -29,56 +29,23 @@ "additionalProperties": false, "minProperties": 1, "properties": { - "domain_names": { - "$ref": "../../../../components/proxy-host-object.json#/properties/domain_names" + "incoming_port": { + "$ref": "../../../../components/stream-object.json#/properties/incoming_port" }, - "forward_scheme": { - "$ref": "../../../../components/proxy-host-object.json#/properties/forward_scheme" + "forwarding_host": { + "$ref": "../../../../components/stream-object.json#/properties/forwarding_host" }, - "forward_host": { - "$ref": "../../../../components/proxy-host-object.json#/properties/forward_host" + "forwarding_port": { + "$ref": "../../../../components/stream-object.json#/properties/forwarding_port" }, - "forward_port": { - "$ref": "../../../../components/proxy-host-object.json#/properties/forward_port" + "tcp_forwarding": { + "$ref": "../../../../components/stream-object.json#/properties/tcp_forwarding" }, - "certificate_id": { - "$ref": "../../../../components/proxy-host-object.json#/properties/certificate_id" - }, - "ssl_forced": { - "$ref": "../../../../components/proxy-host-object.json#/properties/ssl_forced" - }, - "hsts_enabled": { - "$ref": "../../../../components/proxy-host-object.json#/properties/hsts_enabled" - }, - "hsts_subdomains": { - "$ref": "../../../../components/proxy-host-object.json#/properties/hsts_subdomains" - }, - "http2_support": { - "$ref": "../../../../components/proxy-host-object.json#/properties/http2_support" - }, - "block_exploits": { - "$ref": "../../../../components/proxy-host-object.json#/properties/block_exploits" - }, - "caching_enabled": { - "$ref": "../../../../components/proxy-host-object.json#/properties/caching_enabled" - }, - "allow_websocket_upgrade": { - "$ref": "../../../../components/proxy-host-object.json#/properties/allow_websocket_upgrade" - }, - "access_list_id": { - "$ref": "../../../../components/proxy-host-object.json#/properties/access_list_id" - }, - "advanced_config": { - "$ref": "../../../../components/proxy-host-object.json#/properties/advanced_config" - }, - "enabled": { - "$ref": "../../../../components/proxy-host-object.json#/properties/enabled" + "udp_forwarding": { + "$ref": "../../../../components/stream-object.json#/properties/udp_forwarding" }, "meta": { - "$ref": "../../../../components/proxy-host-object.json#/properties/meta" - }, - "locations": { - "$ref": "../../../../components/proxy-host-object.json#/properties/locations" + "$ref": "../../../../components/stream-object.json#/properties/meta" } } } diff --git a/compose.crowdsec.yaml b/compose.crowdsec.yaml index 47d795b74..907e2bda8 100644 --- a/compose.crowdsec.yaml +++ b/compose.crowdsec.yaml @@ -8,7 +8,7 @@ services: - "127.0.0.1:7422:7422" - "127.0.0.1:8080:8080" environment: - - "TZ=Europe/Berlin" + - "TZ=your-timezone" - "COLLECTIONS=ZoeyVid/npmplus" volumes: - "/opt/crowdsec/conf:/etc/crowdsec" diff --git a/compose.geoip.yaml b/compose.geoip.yaml index 5a884f904..6f57e171e 100644 --- a/compose.geoip.yaml +++ b/compose.geoip.yaml @@ -5,7 +5,7 @@ services: restart: always network_mode: bridge environment: - - "TZ=Europe/Berlin" + - "TZ=your-timezone" - "GEOIPUPDATE_EDITION_IDS=GeoLite2-Country GeoLite2-City GeoLite2-ASN" - "GEOIPUPDATE_ACCOUNT_ID=" - "GEOIPUPDATE_LICENSE_KEY=" diff --git a/compose.yaml b/compose.yaml index 7d86f35b4..749a75447 100644 --- a/compose.yaml +++ b/compose.yaml @@ -14,6 +14,8 @@ services: # - "ACME_SERVER=https://acme.zerossl.com/v2/DV90" # acme server to use for NEW certificates, default is (currently, may change later) set to: https://acme-v02.api.letsencrypt.org/directory (letsencrypt) # - "ACME_EAB_KID=123456789abcdef" # Key Identifier for External Account Binding for the acme server # - "ACME_EAB_HMAC_KEY=123456789abcdef" # HMAC key for External Account Binding for the acme server +# - "ACME_MUST_STAPLE=false" # enables must-staple, default true, please only disable it if you get this error MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING in Firefox, see https://github.com/ZoeyVid/NPMplus/discussions/1249, after changing this option you need to recreate (not renew) your certs +# - "ACME_SERVER_TLS_VERIFY=false" # enables checking if ACME_SERVER has a valid TLS cert, default true # - "PUID=1000" # set group id, default 0 (root) # - "PGID=1000" # set user id, default 0 (root), requires PUID # - "NIBEP=48694" # internal port of the NPMplus API, always bound to 127.0.0.1, default 48693, you need to change it, if you want to run multiple npm instances in network mode host @@ -45,7 +47,7 @@ services: # - "LOGROTATIONS=7" # Set how often the access.log should be rotated until it is deleted, default 3 # - "CRT=36" # Set how many hours should be between certbot trying to renew your certs, default 24 # - "IPRT=3" # Set how many hours should be between updating ip ranges from aws and cloudflare, default 1, ignored when SKIP_IP_RANGES is true -# - "GOA=true" # Enables goaccess, requires LOGROTATE, default false --- if you download the GeoLite2-Country.mmdb, GeoLite2-City.mmdb AND GeoLite2-ASN.mmdb file from MaxMind and place them in /opt/npm/etc/goaccess/geoip it will automatically enable GeoIP in goaccess after restarting NPMplus (no need to change GOACLA below), you may also use the compose.geoip.yaml +# - "GOA=true" # Enables goaccess, requires LOGROTATE, default false --- if you download the GeoLite2-Country.mmdb, GeoLite2-City.mmdb AND GeoLite2-ASN.mmdb file from MaxMind and place them in /opt/npm/etc/goaccess/geoip it will automatically enable GeoIP in goaccess after restarting NPMplus (no need to change GOACLA below), you may also deploy the compose.geoip.yaml (please change the timezone) # - "GOACLA=--agent-list --real-os --double-decode --anonymize-ip --anonymize-level=2 --keep-last=7 --with-output-resolver --no-query-string" # Arguments that should be passed to goaccess, default: https://github.com/ZoeyVid/NPMplus/blob/develop/rootfs/usr/local/bin/launch.sh#L50 and: --agent-list --real-os --double-decode --anonymize-ip --anonymize-level=1 --keep-last=30 --with-output-resolver --no-query-string # - "PHP82=true" # Activate PHP82, default false # - "PHP82_APKS=php82-curl php82-openssl" # Add php extensions, see available packages here: https://pkgs.alpinelinux.org/packages?branch=v3.20&repo=community&arch=x86_64&name=php82-*, default none, requires PHP82 @@ -64,4 +66,4 @@ services: # ports: # - "80:80" # environment: -# - "TZ=Europe/Berlin" +# - "TZ=your-timezone" diff --git a/frontend/js/app/nginx/access/list/item.ejs b/frontend/js/app/nginx/access/list/item.ejs index 2ee37a50a..18fe9af73 100644 --- a/frontend/js/app/nginx/access/list/item.ejs +++ b/frontend/js/app/nginx/access/list/item.ejs @@ -1,6 +1,6 @@ -
- +
+
diff --git a/frontend/js/app/nginx/certificates/list/item.ejs b/frontend/js/app/nginx/certificates/list/item.ejs index ffab9ad2a..9f5c2ccc2 100644 --- a/frontend/js/app/nginx/certificates/list/item.ejs +++ b/frontend/js/app/nginx/certificates/list/item.ejs @@ -1,6 +1,6 @@ -
- +
+
diff --git a/frontend/js/app/nginx/dead/list/item.ejs b/frontend/js/app/nginx/dead/list/item.ejs index bb28710c0..db99d00c4 100644 --- a/frontend/js/app/nginx/dead/list/item.ejs +++ b/frontend/js/app/nginx/dead/list/item.ejs @@ -1,6 +1,6 @@ -
- +
+
diff --git a/frontend/js/app/nginx/proxy/list/item.ejs b/frontend/js/app/nginx/proxy/list/item.ejs index e97d6937c..6055ae5fd 100644 --- a/frontend/js/app/nginx/proxy/list/item.ejs +++ b/frontend/js/app/nginx/proxy/list/item.ejs @@ -1,6 +1,6 @@ -
- +
+
diff --git a/frontend/js/app/nginx/redirection/list/item.ejs b/frontend/js/app/nginx/redirection/list/item.ejs index fb5c4d637..00f9e6ef8 100644 --- a/frontend/js/app/nginx/redirection/list/item.ejs +++ b/frontend/js/app/nginx/redirection/list/item.ejs @@ -1,6 +1,6 @@ -
- +
+
diff --git a/frontend/js/app/nginx/stream/list/item.ejs b/frontend/js/app/nginx/stream/list/item.ejs index a8ff83d4c..2ee0e87e6 100644 --- a/frontend/js/app/nginx/stream/list/item.ejs +++ b/frontend/js/app/nginx/stream/list/item.ejs @@ -1,6 +1,6 @@ -
- +
+
diff --git a/frontend/js/i18n/de-lang.json b/frontend/js/i18n/de-lang.json index 09c56a61f..f3bdb4d56 100644 --- a/frontend/js/i18n/de-lang.json +++ b/frontend/js/i18n/de-lang.json @@ -1,292 +1,294 @@ { - "str": { - "email-address": "E-Mail Adresse", - "username": "Nutzername", - "password": "Passwort", - "sign-in": "Anmelden", - "sign-out": "Abmelden", - "try-again": "Erneut versuchen", - "name": "Name", - "email": "E-Mail", - "roles": "Rollen", - "created-on": "Erstellt: {date}", - "save": "Speichern", - "cancel": "Abbrechen", - "close": "Schließen", - "enable": "Aktivieren", - "disable": "Deaktivieren", - "sure": "Ja, ich bin mir sicher", - "disabled": "Deaktiviere", - "choose-file": "Datei auswählen", - "source": "Quelle", - "destination": "Ziel", - "tls": "TLS", + "access-lists": { "access": "Zugang", - "public": "Öffentlich", - "edit": "Bearbeiten", - "delete": "Löschen", - "status": "Status", - "online": "Online", - "offline": "Offline", - "unknown": "Unbekannt", - "expires": "Abgelaufen", - "value": "Wert", - "please-wait": "Bitte warten Sie...", - "all": "Alle", - "any": "Jede" + "access-add": "Hinzufügen", + "add": "Zugangsliste hinzufügen", + "auth-add": "Hinzufügen", + "authorization": "Autorisierung", + "client-count": "{count} {count, select, 1{Regel} other{Regeln}}", + "delete": "Zugriffsliste löschen", + "delete-confirm": "Sind Sie sicher, dass Sie diese Zugangsliste löschen wollen?", + "delete-has-hosts": "Diese Zugriffsliste ist verbunden mit {count} Proxy-Hosts. Sie werden nach dem Löschen öffentlich zugänglich.", + "details": "Einzelheiten", + "empty": "Es gibt keine Zugriffslisten", + "form-title": "{id, select, undefined{Neue} other{Bearbeitung}} Zugriffsliste", + "help-content": "Zugriffslisten bieten eine Black- oder Whitelist für bestimmte Client-IP-Adressen zusammen mit der Authentifizierung für die Proxy-Hosts über die Basic HTTP Authentication.\nSie können mehrere Client-Regeln, Benutzer:innamen und Kennwörter für eine einzelne Zugriffsliste konfigurieren und diese dann auf einen Proxy-Host anwenden.\nDies ist besonders nützlich für weitergeleitete Webdienste, die keine Authentifizierungsmechanismen eingebaut haben oder die Sie vor dem Zugriff durch unbekannte Clients schützen möchten.", + "help-title": "Was ist eine Zugangsliste?", + "item-count": "{count} Benutzer:innen", + "pass-auth": "Anmeldeinformationen nicht an das Backend des Hosts weitergeben", + "proxy-host-count": "{count} {count, select, 1{Proxy Host} other{Proxy Hosts}}", + "public": "Öffentlicher Zugang", + "public-sub": "Keine Zugangsbeschränkungen", + "satisfy": "Zufriedenstellen", + "satisfy-any": "Zugriff zulassen, wenn mindestens eine Autorisierungsmethode erfolgreich war", + "search": "Suche Zugriffslisten...", + "title": "Zugriffslisten" }, - "login": { - "title": "Anmeldung bei Ihrem Konto" + "all-hosts": { + "advanced": "Erweitert", + "advanced-config": "Individuelle Nginx-Konfiguration", + "advanced-config-header-info": "Bitte beachten Sie, dass das Hinzufügen eines Pfads '/' die Proxy-Konfiguration überschreibt", + "advanced-config-var-headline": "Diese Proxy-Details sind als nginx-Variablen verfügbar:", + "advanced-warning": "Geben Sie hier Ihre eigene Nginx-Konfiguration ein - auf eigenes Risiko!", + "cert-provider": "Zertifikat-Anbieter", + "details": "Details", + "domain-names": "Domain-Namen", + "empty-subtitle": "{manage, select, true{Warum erstellen Sie keinen?} other{Und Sie haben nicht die Erlaubnis, einen zu erstellen.}}", + "enable-brotli": "Brotli einschalten", + "enable-crs": "CoreRuleSet aktivieren (Erfordert ModSecurity)", + "enable-hsts": "Aktivieren Sie HSTS und Sicherheits-Header", + "enable-http3": "Aktiviere HTTP/3-Quic", + "enable-modsec": "ModSecurity einschalten", + "force-https": "Erzwinge HTTPS", + "locations": "Individuelle Pfade", + "new-cert": "Ein neues TLS-Zertifikat anfordern", + "no-tls": "Dieser Host benutzt kein HTTPS", + "none": "Keine", + "tls-certificate": "TLS-Zertifikat", + "with-certbot": "mit Certbot" }, - "main": { - "app": "NPMplus", - "version": "0.0.0", - "welcome": "Willkommen bei NPMplus", - "logged-in": "Sie sind eingeloggt als {name}", - "unknown-user": "Unbekannte:r Benutzer:in", - "sign-in-as": "Melden Sie sich wieder als {name} an" + "audit-log": { + "access-list": "Zugriffsliste", + "certificate": "Zertifikat", + "created": "Erstellt {name}", + "date": "Date", + "dead-host": "404 Host", + "deleted": "Gelöscht {name}", + "disabled": "Deaktiviert {name}", + "empty": "Es gibt keine Protokolle.", + "empty-subtitle": "Sobald Sie oder ein:e andere:r Benutzer:in etwas ändern, wird der Verlauf dieser Ereignisse hier angezeigt.", + "enabled": "Aktiviert {name}", + "meta-title": "Details zur Veranstaltung", + "proxy-host": "Proxy-Host", + "redirection-host": "Weiterleitungs Host", + "renewed": "Erneuert {name}", + "search": "Protokolle suchen...", + "stream": "Stream", + "title": "Audit Protokoll", + "updated": "Aktualisiert {name}", + "user": "Benutzer:in", + "view-meta": "Details anzeigen" }, - "roles": { - "title": "Rollen", - "admin": "Administrator:in", - "user": "Benutzer:in" + "certificates": { + "add": "TLS-Zertifikat hinzufügen", + "delete": "TLS-Zertifikat löschen", + "delete-confirm": "Sind Sie sicher, dass Sie dieses TLS-Zertifikat löschen wollen? Alle Hosts, die es verwenden, müssen später aktualisiert werden.", + "download": "Herunterladen", + "empty": "Es gibt keine TLS-Zertifikate", + "force-renew": "Jetzt erneuern", + "form-title": "Hinzufügen {provider, select, letsencrypt{Certbot} other{Custom}} Zertifikat", + "help-content": "TLS-Zertifikate (früher bekannt als SSL-Zertifikate) sind eine Art Verschlüsselungsschlüssel, mit dem Ihre Website für die:den Endbenutzer:in verschlüsselt werden kann.\nNPMplus verwendet standardmäßig einen Dienst namens Let's Encrypt, um kostenlos TLS-Zertifikate auszustellen.\nWenn Sie persönliche Informationen, Passwörter oder sensible Daten hinter NPM haben, ist es wahrscheinlich eine gute Idee, ein Zertifikat zu verwenden.\nNPMplus unterstützt auch die DNS-Authentifizierung, wenn Sie Ihre Website nicht mit dem Internet verbinden oder wenn Sie nur ein Platzhalterzertifikat benötigen.", + "help-title": "TLS-Zertifikate", + "other-certificate": "Zertifikat", + "other-certificate-key": "Zertifikat Schlüssel", + "other-intermediate-certificate": "Zwischenzeugnis", + "reachability-404": "Es wurde ein Server unter dieser Domain gefunden, aber es scheint nicht NPMplus zu sein. Bitte stellen Sie sicher, dass Ihre Domain auf die IP-Adresse verweist, auf der Ihre NPMplus-Instanz läuft.", + "reachability-failed-to-check": "Aufgrund eines Kommunikationsfehlers mit site24x7.com konnte die Erreichbarkeit nicht überprüft werden.", + "reachability-failed-to-reach-api": "Die Kommunikation mit der API ist fehlgeschlagen. Läuft NPMplus korrekt?", + "reachability-info": "Testen Sie mit Site24x7, ob die Domains aus dem öffentlichen Internet erreichbar sind. Bei Verwendung der DNS-Challenge ist dies nicht notwendig.", + "reachability-not-resolved": "Es ist kein Server unter dieser Domain verfügbar. Bitte stellen Sie sicher, dass Ihre Domain existiert und auf die IP-Adresse verweist, auf der Ihre NPMplus-Instanz läuft, und ggf. Port 80 in Ihrem Router weitergeleitet wird.", + "reachability-ok": "Ihr Server ist erreichbar und das Erstellen von Zertifikaten sollte möglich sein.", + "reachability-other": "Es wurde ein Server unter dieser Domain gefunden, aber er hat einen unerwarteten Statuscode {code} zurückgegeben. Ist es der NPMplus-Server? Stellen Sie sicher, dass Ihre Domain auf die IP-Adresse verweist, auf der Ihre NPMplus-Instanz läuft.", + "reachability-title": "Erreichbarkeit des Servers testen", + "reachability-wrong-data": "Unter dieser Domäne wurde ein Server gefunden, der jedoch unerwartete Daten zurückgegeben hat. Ist es der NPMplus-Server? Stellen Sie sicher, dass Ihre Domain auf die IP-Adresse verweist, auf der Ihre NPMplus-Instanz läuft.", + "renew-title": "Zertifikat erneuern", + "search": "Suche Zertifikat...", + "test-reachability": "Erreichbarkeit des Servers testen", + "title": "TLS-Zertifikate" }, - "menu": { - "dashboard": "Dashboard", - "hosts": "Hosts" + "dashboard": { + "title": "Hallo {name}" + }, + "dead-hosts": { + "add": "404 Host hinzufügen", + "delete": "404 Host löschen", + "delete-confirm": "Sind Sie sicher, dass Sie diesen 404-Host löschen wollen?", + "empty": "Es gibt keine 404 Hosts", + "form-title": "{id, select, undefined{Neuer} other{Bearbeitung}} 404 Host", + "help-content": "Ein 404-Host ist einfach eine Host-Einrichtung, die eine 404-Seite anzeigt.\nDies kann nützlich sein, wenn Ihre Domain in Suchmaschinen gelistet ist und Sie eine schönere Fehlerseite bereitstellen wollen oder um den Suchindexierern mitzuteilen, dass die Domain-Seiten nicht mehr existieren.\nEin weiterer Vorteil dieses Hosts besteht darin, dass man die Logs der Zugriffe auf ihn verfolgen und die Verweiser einsehen kann.", + "help-title": "Was ist ein 404-Host?", + "search": "Suche Host..", + "title": "404 Hosts" }, "footer": { - "repo": "Repository auf GitHub", "copy-npm": " - © 2024 jc21.com NPM", "copy-npmplus": " - und © 2024 ZoeyVid NPMplus", "license": " - MIT-Lizenz", + "repo": "Repository auf GitHub", "theme": " - Thema von Tabler v0.0.31" }, - "dashboard": { - "title": "Hallo {name}" - }, - "all-hosts": { - "empty-subtitle": "{manage, select, true{Warum erstellen Sie keinen?} other{Und Sie haben nicht die Erlaubnis, einen zu erstellen.}}", - "details": "Details", - "force-https": "Erzwinge HTTPS", - "enable-brotli": "Brotli einschalten", - "domain-names": "Domain-Namen", - "cert-provider": "Zertifikat-Anbieter", - "enable-modsec": "ModSecurity einschalten", - "enable-crs": "CoreRuleSet aktivieren (Erfordert ModSecurity)", - "tls-certificate": "TLS-Zertifikat", - "none": "Keine", - "new-cert": "Ein neues TLS-Zertifikat anfordern", - "with-certbot": "mit Certbot", - "no-tls": "Dieser Host benutzt kein HTTPS", - "advanced": "Erweitert", - "advanced-warning": "Geben Sie hier Ihre eigene Nginx-Konfiguration ein - auf eigenes Risiko!", - "advanced-config": "Individuelle Nginx-Konfiguration", - "advanced-config-var-headline": "Diese Proxy-Details sind als nginx-Variablen verfügbar:", - "advanced-config-header-info": "Bitte beachten Sie, dass das Hinzufügen eines Pfads '/' die Proxy-Konfiguration überschreibt", - "enable-hsts": "Aktivieren Sie HSTS und Sicherheits-Header", - "enable-http3": "Aktiviere HTTP/3-Quic", - "locations": "Individuelle Pfade" - }, "locations": { - "new_location": "Pfad hinzufügen", - "path": "/pfad", + "delete": "Löschen", "location_label": "Pfad definieren", - "delete": "Löschen" + "new_location": "Pfad hinzufügen", + "path": "/pfad" }, - "tls": { - "letsencrypt": "Certbot", - "certbot": "Certbot", - "other": "Individuell", - "none": "Nur HTTP", - "certbot-email": "E-Mail Adresse für Certbot", - "certbot-agree": "Ich stimme den Let's Encrypt Terms of Service / ToS der individuell eingestellten CA zu", - "delete-tls": "Die angehängten TLS-Zertifikate werden NICHT entfernt, sie müssen manuell entfernt werden.", - "hosts-warning": "Diese Domänen müssen bereits so konfiguriert sein, dass sie auf diese Installation verweisen", - "no-wildcard-without-dns": "Zertifikat kann nicht für Wildcard-Domains angefordert werden, wenn keine DNS-Challenge verwendet wird", - "dns-challenge": "Verwenden Sie eine DNS-Herausforderung", - "certbot-warning": "Dieser Abschnitt erfordert einige Kenntnisse über Certbot und seine DNS-Plugins. Bitte konsultieren Sie die Dokumentation der jeweiligen Plugins.", - "dns-provider": "DNS-Anbieter", - "credentials-file-content": "Inhalt der Berechtigungsnachweisdatei", - "credentials-file-content-info": "Dieses Plugin erfordert eine Konfigurationsdatei, die ein API-Token oder andere Anmeldeinformationen für Ihren Anbieter enthält", - "stored-as-plaintext-info": "Diese Daten werden als Klartext in der Datenbank und in einer Datei gespeichert!", - "propagation-seconds": "Ausbreitung in Sekunden", - "propagation-seconds-info": "Leer lassen, um den Standardwert des Plugins zu verwenden. Anzahl der Sekunden, die auf die DNS-Verbreitung gewartet werden soll.", - "processing-info": "Verarbeitung... Dies kann ein paar Minuten dauern.", - "passphrase-protection-support-info": "Schlüsseldateien, die mit einer Passphrase geschützt sind, werden nicht unterstützt." + "login": { + "title": "Anmeldung bei Ihrem Konto" + }, + "main": { + "app": "NPMplus", + "logged-in": "Sie sind eingeloggt als {name}", + "sign-in-as": "Melden Sie sich wieder als {name} an", + "unknown-user": "Unbekannte:r Benutzer:in", + "version": "0.0.0", + "welcome": "Willkommen bei NPMplus" + }, + "menu": { + "dashboard": "Dashboard", + "hosts": "Hosts" }, "proxy-hosts": { - "title": "Proxy-Hosts", - "empty": "Es gibt keine Proxy-Hosts", + "access-list": "Zugriffsliste", "add": "Proxy-Host hinzufügen", + "allow-websocket-upgrade": "Websockets-Unterstützung", + "custom-forward-host-help": "Fügen Sie einen Pfad für die Weiterleitung von Unterordnern hinzu.\nBeispiel: 203.0.113.25/pfad/", + "delete": "Proxy-Host löschen", + "delete-confirm": "Sind Sie sicher, dass Sie den Proxy-Host löschen wollen für: {domains}?", + "empty": "Es gibt keine Proxy-Hosts", "form-title": "{id, select, undefined{Neuer} other{Bearbeitung}} Proxy-Host", - "forward-scheme": "Schema", "forward-host": "Hostname / IP weiterleiten", "forward-port": "Port weiterleiten", - "delete": "Proxy-Host löschen", - "delete-confirm": "Sind Sie sicher, dass Sie den Proxy-Host löschen wollen für: {domains}?", - "help-title": "Was ist ein Proxy-Host?", + "forward-scheme": "Schema", "help-content": "Ein Proxy-Host ist der eingehende Endpunkt für einen Webdienst, den Sie weiterleiten möchten.\nEr bietet eine optionale TLS-Terminierung für Ihren Dienst, der möglicherweise keine TLS-Unterstützung eingebaut hat.\nProxy-Hosts sind die häufigste Anwendung für den NPMplus.", - "access-list": "Zugriffsliste", - "allow-websocket-upgrade": "Websockets-Unterstützung", - "custom-forward-host-help": "Fügen Sie einen Pfad für die Weiterleitung von Unterordnern hinzu.\nBeispiel: 203.0.113.25/pfad/", - "search": "Suche Host.." + "help-title": "Was ist ein Proxy-Host?", + "search": "Suche Host..", + "title": "Proxy-Hosts" }, "redirection-hosts": { - "title": "Weiterleitungs-Hosts", - "empty": "Es gibt keine Weiterleitungs-Hosts", "add": "Weiterleitungs-Host hinzufügen", - "form-title": "{id, select, undefined{Neuer} other{Bearbeitung}} Weiterleitungs Host", - "forward-scheme": "Schema", - "forward-http-status-code": "HTTP Code", - "forward-domain": "Ziel Domain und Pfad (ohne https:// bzw. http://)", - "preserve-path": "Pfad beibehalten", "delete": "Weiterleitungs-Host löschen", "delete-confirm": "Sind Sie sicher, dass Sie den Weiterleitungs-Host löschen wollen für: {domains}?", - "help-title": "Was ist ein Weiterleitungs Host?", + "empty": "Es gibt keine Weiterleitungs-Hosts", + "form-title": "{id, select, undefined{Neuer} other{Bearbeitung}} Weiterleitungs Host", + "forward-domain": "Ziel Domain und Pfad (ohne https:// bzw. http://)", + "forward-http-status-code": "HTTP Code", + "forward-scheme": "Schema", "help-content": "Ein Weiterleitungs Host leitet Anfragen von der eingehenden Domain um und schiebt den Besucher auf eine andere Domain.\nDer häufigste Grund für die Verwendung dieser Art von Host ist, wenn Ihre Website die Domäne wechselt, aber noch Suchmaschinen- oder Referrer-Links auf die alte Domäne verweisen.", - "search": "Suche Host.." + "help-title": "Was ist ein Weiterleitungs Host?", + "preserve-path": "Pfad beibehalten", + "search": "Suche Host..", + "title": "Weiterleitungs-Hosts" }, - "dead-hosts": { - "title": "404 Hosts", - "empty": "Es gibt keine 404 Hosts", - "add": "404 Host hinzufügen", - "form-title": "{id, select, undefined{Neuer} other{Bearbeitung}} 404 Host", - "delete": "404 Host löschen", - "delete-confirm": "Sind Sie sicher, dass Sie diesen 404-Host löschen wollen?", - "help-title": "Was ist ein 404-Host?", - "help-content": "Ein 404-Host ist einfach eine Host-Einrichtung, die eine 404-Seite anzeigt.\nDies kann nützlich sein, wenn Ihre Domain in Suchmaschinen gelistet ist und Sie eine schönere Fehlerseite bereitstellen wollen oder um den Suchindexierern mitzuteilen, dass die Domain-Seiten nicht mehr existieren.\nEin weiterer Vorteil dieses Hosts besteht darin, dass man die Logs der Zugriffe auf ihn verfolgen und die Verweiser einsehen kann.", - "search": "Suche Host.." + "roles": { + "admin": "Administrator:in", + "title": "Rollen", + "user": "Benutzer:in" + }, + "settings": { + "default-site": "Standard-Seite", + "default-site-404": "404 Seite", + "default-site-444": "Verbindung abbrechen - erlaubt nur certbot dns-challenge", + "default-site-congratulations": "Glückwunsch-Seite", + "default-site-description": "Was angezeigt werden soll, wenn Nginx einen unbekannten Host antrifft", + "default-site-html": "Individuelle Seite", + "default-site-redirect": "Weiterleitung", + "title": "Einstellungen" + }, + "str": { + "access": "Zugang", + "all": "Alle", + "any": "Jede", + "cancel": "Abbrechen", + "choose-file": "Datei auswählen", + "close": "Schließen", + "created-on": "Erstellt: {date}", + "delete": "Löschen", + "destination": "Ziel", + "disable": "Deaktivieren", + "disabled": "Deaktiviere", + "edit": "Bearbeiten", + "email": "E-Mail", + "email-address": "E-Mail Adresse", + "enable": "Aktivieren", + "expires": "Abgelaufen", + "name": "Name", + "offline": "Offline", + "online": "Online", + "password": "Passwort", + "please-wait": "Bitte warten Sie...", + "public": "Öffentlich", + "roles": "Rollen", + "save": "Speichern", + "sign-in": "Anmelden", + "sign-out": "Abmelden", + "source": "Quelle", + "status": "Status", + "sure": "Ja, ich bin mir sicher", + "tls": "TLS", + "try-again": "Erneut versuchen", + "unknown": "Unbekannt", + "username": "Nutzername", + "value": "Wert" }, "streams": { - "title": "Streams", - "empty": "Es gibt keine Streams", "add": "Stream hinzufügen", + "delete": "Stream löschen", + "delete-confirm": "Sind Sie sicher, dass Sie diesen Stream löschen möchten?", + "empty": "Es gibt keine Streams", "form-title": "{id, select, undefined{Neuer} other{Bearbeitung}} Stream", - "incoming-port": "Eingehender Port", + "forward-type-error": "Mindestens eine Art von Protokollen muss aktiviert sein", "forwarding-host": "Host weiterleiten", "forwarding-port": "Port weiterleiten", - "tcp-forwarding": "TCP-Weiterleitung", - "udp-forwarding": "UDP-Weiterleitung", - "forward-type-error": "Mindestens eine Art von Protokollen muss aktiviert sein", + "help-content": "Ein Stream ist eine relativ neue Funktion für Nginx, die dazu dient, TCP/UDP-Datenverkehr direkt an einen anderen Computer im Netzwerk weiterzuleiten.\nWenn Sie Spieleserver, FTP- oder SSH-Server betreiben, kann dies sehr nützlich sein.", + "help-title": "Was ist ein Stream?", + "incoming-port": "Eingehender Port", "protocol": "Protokoll", + "search": "Suche Streams...", "tcp": "TCP", + "tcp-forwarding": "TCP-Weiterleitung", + "title": "Streams", "udp": "UDP", - "delete": "Stream löschen", - "delete-confirm": "Sind Sie sicher, dass Sie diesen Stream löschen möchten?", - "help-title": "Was ist ein Stream?", - "help-content": "Ein Stream ist eine relativ neue Funktion für Nginx, die dazu dient, TCP/UDP-Datenverkehr direkt an einen anderen Computer im Netzwerk weiterzuleiten.\nWenn Sie Spieleserver, FTP- oder SSH-Server betreiben, kann dies sehr nützlich sein.", - "search": "Suche Streams..." - }, - "certificates": { - "title": "TLS-Zertifikate", - "empty": "Es gibt keine TLS-Zertifikate", - "add": "TLS-Zertifikat hinzufügen", - "form-title": "Hinzufügen {provider, select, letsencrypt{Certbot} other{Custom}} Zertifikat", - "delete": "TLS-Zertifikat löschen", - "delete-confirm": "Sind Sie sicher, dass Sie dieses TLS-Zertifikat löschen wollen? Alle Hosts, die es verwenden, müssen später aktualisiert werden.", - "help-title": "TLS-Zertifikate", - "help-content": "TLS-Zertifikate (früher bekannt als SSL-Zertifikate) sind eine Art Verschlüsselungsschlüssel, mit dem Ihre Website für die:den Endbenutzer:in verschlüsselt werden kann.\nNPMplus verwendet standardmäßig einen Dienst namens Let's Encrypt, um kostenlos TLS-Zertifikate auszustellen.\nWenn Sie persönliche Informationen, Passwörter oder sensible Daten hinter NPM haben, ist es wahrscheinlich eine gute Idee, ein Zertifikat zu verwenden.\nNPMplus unterstützt auch die DNS-Authentifizierung, wenn Sie Ihre Website nicht mit dem Internet verbinden oder wenn Sie nur ein Platzhalterzertifikat benötigen.", - "other-certificate": "Zertifikat", - "other-certificate-key": "Zertifikat Schlüssel", - "other-intermediate-certificate": "Zwischenzeugnis", - "force-renew": "Jetzt erneuern", - "test-reachability": "Erreichbarkeit des Servers testen", - "reachability-title": "Erreichbarkeit des Servers testen", - "reachability-info": "Testen Sie mit Site24x7, ob die Domains aus dem öffentlichen Internet erreichbar sind. Bei Verwendung der DNS-Challenge ist dies nicht notwendig.", - "reachability-failed-to-reach-api": "Die Kommunikation mit der API ist fehlgeschlagen. Läuft NPMplus korrekt?", - "reachability-failed-to-check": "Aufgrund eines Kommunikationsfehlers mit site24x7.com konnte die Erreichbarkeit nicht überprüft werden.", - "reachability-ok": "Ihr Server ist erreichbar und das Erstellen von Zertifikaten sollte möglich sein.", - "reachability-404": "Es wurde ein Server unter dieser Domain gefunden, aber es scheint nicht NPMplus zu sein. Bitte stellen Sie sicher, dass Ihre Domain auf die IP-Adresse verweist, auf der Ihre NPMplus-Instanz läuft.", - "reachability-not-resolved": "Es ist kein Server unter dieser Domain verfügbar. Bitte stellen Sie sicher, dass Ihre Domain existiert und auf die IP-Adresse verweist, auf der Ihre NPMplus-Instanz läuft, und ggf. Port 80 in Ihrem Router weitergeleitet wird.", - "reachability-wrong-data": "Unter dieser Domäne wurde ein Server gefunden, der jedoch unerwartete Daten zurückgegeben hat. Ist es der NPMplus-Server? Stellen Sie sicher, dass Ihre Domain auf die IP-Adresse verweist, auf der Ihre NPMplus-Instanz läuft.", - "reachability-other": "Es wurde ein Server unter dieser Domain gefunden, aber er hat einen unerwarteten Statuscode {code} zurückgegeben. Ist es der NPMplus-Server? Stellen Sie sicher, dass Ihre Domain auf die IP-Adresse verweist, auf der Ihre NPMplus-Instanz läuft.", - "download": "Herunterladen", - "renew-title": "Zertifikat erneuern", - "search": "Suche Zertifikat..." + "udp-forwarding": "UDP-Weiterleitung" }, - "access-lists": { - "title": "Zugriffslisten", - "empty": "Es gibt keine Zugriffslisten", - "add": "Zugangsliste hinzufügen", - "form-title": "{id, select, undefined{Neue} other{Bearbeitung}} Zugriffsliste", - "delete": "Zugriffsliste löschen", - "delete-confirm": "Sind Sie sicher, dass Sie diese Zugangsliste löschen wollen?", - "public": "Öffentlicher Zugang", - "public-sub": "Keine Zugangsbeschränkungen", - "help-title": "Was ist eine Zugangsliste?", - "help-content": "Zugriffslisten bieten eine Black- oder Whitelist für bestimmte Client-IP-Adressen zusammen mit der Authentifizierung für die Proxy-Hosts über die Basic HTTP Authentication.\nSie können mehrere Client-Regeln, Benutzer:innamen und Kennwörter für eine einzelne Zugriffsliste konfigurieren und diese dann auf einen Proxy-Host anwenden.\nDies ist besonders nützlich für weitergeleitete Webdienste, die keine Authentifizierungsmechanismen eingebaut haben oder die Sie vor dem Zugriff durch unbekannte Clients schützen möchten.", - "item-count": "{count} Benutzer:innen", - "client-count": "{count} {count, select, 1{Regel} other{Regeln}}", - "proxy-host-count": "{count} {count, select, 1{Proxy Host} other{Proxy Hosts}}", - "delete-has-hosts": "Diese Zugriffsliste ist verbunden mit {count} Proxy-Hosts. Sie werden nach dem Löschen öffentlich zugänglich.", - "details": "Einzelheiten", - "authorization": "Autorisierung", - "access": "Zugang", - "satisfy": "Zufriedenstellen", - "satisfy-any": "Zugriff zulassen, wenn mindestens eine Autorisierungsmethode erfolgreich war", - "pass-auth": "Anmeldeinformationen nicht an das Backend des Hosts weitergeben", - "access-add": "Hinzufügen", - "auth-add": "Hinzufügen", - "search": "Suche Zugriffslisten..." + "tls": { + "certbot": "Certbot", + "certbot-agree": "Ich stimme den Let's Encrypt Terms of Service / ToS der individuell eingestellten CA zu", + "certbot-email": "E-Mail Adresse für Certbot", + "certbot-warning": "Dieser Abschnitt erfordert einige Kenntnisse über Certbot und seine DNS-Plugins. Bitte konsultieren Sie die Dokumentation der jeweiligen Plugins.", + "credentials-file-content": "Inhalt der Berechtigungsnachweisdatei", + "credentials-file-content-info": "Dieses Plugin erfordert eine Konfigurationsdatei, die ein API-Token oder andere Anmeldeinformationen für Ihren Anbieter enthält", + "delete-tls": "Die angehängten TLS-Zertifikate werden NICHT entfernt, sie müssen manuell entfernt werden.", + "dns-challenge": "Verwenden Sie eine DNS-Herausforderung", + "dns-provider": "DNS-Anbieter", + "hosts-warning": "Diese Domänen müssen bereits so konfiguriert sein, dass sie auf diese Installation verweisen", + "letsencrypt": "Certbot", + "no-wildcard-without-dns": "Zertifikat kann nicht für Wildcard-Domains angefordert werden, wenn keine DNS-Challenge verwendet wird", + "none": "Nur HTTP", + "other": "Individuell", + "passphrase-protection-support-info": "Schlüsseldateien, die mit einer Passphrase geschützt sind, werden nicht unterstützt.", + "processing-info": "Verarbeitung... Dies kann ein paar Minuten dauern.", + "propagation-seconds": "Ausbreitung in Sekunden", + "propagation-seconds-info": "Leer lassen, um den Standardwert des Plugins zu verwenden. Anzahl der Sekunden, die auf die DNS-Verbreitung gewartet werden soll.", + "stored-as-plaintext-info": "Diese Daten werden als Klartext in der Datenbank und in einer Datei gespeichert!" }, "users": { - "title": "Benutzer:in", - "default_error": "Standard-E-Mail-Adresse muss geändert werden", "add": "Nutzer:in hinzufügen", - "nickname": "Spitzname", - "full-name": "Vollständiger Name", - "edit-details": "Details bearbeiten", + "admin-perms": "Diese:r Benutzer:in ist ein:e Administrator:in und einige Elemente können nicht geändert werden", "change-password": "Passwort ändern", - "edit-permissions": "Berechtigungen bearbeiten", - "sign-in-as": "Als Benutzer:in anmelden", - "form-title": "{id, select, undefined{Neue:r} other{Bearbeitung}} Benutzer:in", + "confirm-password": "Bestätigen Sie Ihr Passwort", + "current-password": "Aktuelles Passwort", + "default_error": "Standard-E-Mail-Adresse muss geändert werden", "delete": "Löschen {name, select, undefined{Benutzer:in} other{{name}}}", "delete-confirm": "Sind Sie sicher, dass Sie {name} löschen wollen?", - "password-title": "Passwort ändern{self, select, false{ für {name}} other{}}", - "current-password": "Aktuelles Passwort", + "edit-details": "Details bearbeiten", + "edit-permissions": "Berechtigungen bearbeiten", + "form-title": "{id, select, undefined{Neue:r} other{Bearbeitung}} Benutzer:in", + "full-name": "Vollständiger Name", "new-password": "Neues Passwort", - "confirm-password": "Bestätigen Sie Ihr Passwort", + "nickname": "Spitzname", + "owned-by": "Im Besitz von {name}", + "owned-by-deleted": "Gelöschte:r Benutzer:in", + "password-title": "Passwort ändern{self, select, false{ für {name}} other{}}", + "perm-hidden": "Versteckt", + "perm-manage": "Verwalten", + "perm-view": "Nur Ansicht", "permissions-title": "Berechtigungen für {name}", - "admin-perms": "Diese:r Benutzer:in ist ein:e Administrator:in und einige Elemente können nicht geändert werden", "perms-visibility": "Sichtbarkeit der Einträge", - "perms-visibility-user": "Nur erstellte Einträge", "perms-visibility-all": "Alle Einträge", - "perm-manage": "Verwalten", - "perm-view": "Nur Ansicht", - "perm-hidden": "Versteckt", - "search": "Benutzer:in suchen..." - }, - "audit-log": { - "title": "Audit Protokoll", - "empty": "Es gibt keine Protokolle.", - "empty-subtitle": "Sobald Sie oder ein:e andere:r Benutzer:in etwas ändern, wird der Verlauf dieser Ereignisse hier angezeigt.", - "proxy-host": "Proxy-Host", - "redirection-host": "Weiterleitungs Host", - "dead-host": "404 Host", - "stream": "Stream", - "user": "Benutzer:in", - "certificate": "Zertifikat", - "access-list": "Zugriffsliste", - "created": "Erstellt {name}", - "updated": "Aktualisiert {name}", - "deleted": "Gelöscht {name}", - "enabled": "Aktiviert {name}", - "disabled": "Deaktiviert {name}", - "renewed": "Erneuert {name}", - "meta-title": "Details zur Veranstaltung", - "view-meta": "Details anzeigen", - "date": "Date", - "search": "Protokolle suchen..." - }, - "settings": { - "title": "Einstellungen", - "default-site": "Standard-Seite", - "default-site-description": "Was angezeigt werden soll, wenn Nginx einen unbekannten Host antrifft", - "default-site-congratulations": "Glückwunsch-Seite", - "default-site-404": "404 Seite", - "default-site-444": "Verbindung abbrechen - erlaubt nur certbot dns-challenge", - "default-site-html": "Individuelle Seite", - "default-site-redirect": "Weiterleitung" + "perms-visibility-user": "Nur erstellte Einträge", + "search": "Benutzer:in suchen...", + "sign-in-as": "Als Benutzer:in anmelden", + "title": "Benutzer:in" } } diff --git a/frontend/js/i18n/en-lang.json b/frontend/js/i18n/en-lang.json index b37ca115a..f30670109 100644 --- a/frontend/js/i18n/en-lang.json +++ b/frontend/js/i18n/en-lang.json @@ -1,292 +1,294 @@ { - "str": { - "email-address": "Email address", - "username": "Username", - "password": "Password", - "sign-in": "Sign in", - "sign-out": "Sign out", - "try-again": "Try again", - "name": "Name", - "email": "Email", - "roles": "Roles", - "created-on": "Created: {date}", - "save": "Save", - "cancel": "Cancel", - "close": "Close", - "enable": "Enable", - "disable": "Disable", - "sure": "Yes I'm Sure", - "disabled": "Disabled", - "choose-file": "Choose file", - "source": "Source", - "destination": "Destination", - "tls": "TLS", + "access-lists": { "access": "Access", - "public": "Public", - "edit": "Edit", - "delete": "Delete", - "status": "Status", - "online": "Online", - "offline": "Offline", - "unknown": "Unknown", - "expires": "Expires", - "value": "Value", - "please-wait": "Please wait...", - "all": "All", - "any": "Any" + "access-add": "Add", + "add": "Add Access List", + "auth-add": "Add", + "authorization": "Authorization", + "client-count": "{count} {count, select, 1{Rule} other{Rules}}", + "delete": "Delete Access List", + "delete-confirm": "Are you sure you want to delete this access list?", + "delete-has-hosts": "This Access List is associated with {count} Proxy Hosts. They will become publicly available upon deletion.", + "details": "Details", + "empty": "There are no Access Lists", + "form-title": "{id, select, undefined{New} other{Edit}} Access List", + "help-content": "Access Lists provide a blacklist or whitelist of specific client IP addresses along with authentication for the Proxy Hosts via Basic HTTP Authentication.\nYou can configure multiple client rules, usernames and passwords for a single Access List and then apply that to a Proxy Host.\nThis is most useful for forwarded web services that do not have authentication mechanisms built in or that you want to protect from access by unknown clients.", + "help-title": "What is an Access List?", + "item-count": "{count} {count, select, 1{User} other{Users}}", + "pass-auth": "Don't pass credentials to backend of host", + "proxy-host-count": "{count} {count, select, 1{Proxy Host} other{Proxy Hosts}}", + "public": "Publicly Accessible", + "public-sub": "No Access Restrictions", + "satisfy": "Satisfy", + "satisfy-any": "Allow access if at least one authorization method succeeded", + "search": "Search Access…", + "title": "Access Lists" }, - "login": { - "title": "Login to your account" + "all-hosts": { + "advanced": "Advanced", + "advanced-config": "Custom Nginx Configuration", + "advanced-config-header-info": "Please note, adding a location '/' will overwrite the proxy configuration", + "advanced-config-var-headline": "These proxy details are available as nginx variables:", + "advanced-warning": "Enter your custom Nginx configuration here at your own risk!", + "cert-provider": "Certificate Provider", + "details": "Details", + "domain-names": "Domain Names", + "empty-subtitle": "{manage, select, true{Why don't you create one?} other{And you don't have permission to create one.}}", + "enable-brotli": "Enable Brotli", + "enable-crs": "Enable CoreRuleSet (Requires ModSecurity)", + "enable-hsts": "Enable HSTS and security headers", + "enable-http3": "Enable HTTP/3-Quic", + "enable-modsec": "Enable ModSecurity", + "force-https": "Force HTTPS", + "locations": "Custom locations", + "new-cert": "Request a new TLS Certificate", + "no-tls": "This host will not use HTTPS", + "none": "None", + "tls-certificate": "TLS Certificate", + "with-certbot": "with Certbot" }, - "main": { - "app": "NPMplus", - "version": "0.0.0", - "welcome": "Welcome to NPMplus", - "logged-in": "You are logged in as {name}", - "unknown-user": "Unknown User", - "sign-in-as": "Sign back in as {name}" + "audit-log": { + "access-list": "Access List", + "certificate": "Certificate", + "created": "Created {name}", + "date": "Date", + "dead-host": "404 Host", + "deleted": "Deleted {name}", + "disabled": "Disabled {name}", + "empty": "There are no logs.", + "empty-subtitle": "As soon as you or another user changes something, history of those events will show up here.", + "enabled": "Enabled {name}", + "meta-title": "Details for Event", + "proxy-host": "Proxy Host", + "redirection-host": "Redirection Host", + "renewed": "Renewed {name}", + "search": "Search Log…", + "stream": "Stream", + "title": "Audit Log", + "updated": "Updated {name}", + "user": "User", + "view-meta": "View Details" }, - "roles": { - "title": "Roles", - "admin": "Administrator", - "user": "User" + "certificates": { + "add": "Add TLS Certificate", + "delete": "Delete TLS Certificate", + "delete-confirm": "Are you sure you want to delete this TLS Certificate? Any hosts using it will need to be updated later.", + "download": "Download", + "empty": "There are no TLS Certificates", + "force-renew": "Renew Now", + "form-title": "Add {provider, select, letsencrypt{Certbot} other{Custom}} Certificate", + "help-content": "TLS certificates (previously known as SSL Certificates) are a form of encryption key which allows your site to be encrypted for the end user.\nNPMplus uses by default a service called Let's Encrypt to issue TLS certificates for free.\nIf you have any sort of personal information, passwords, or sensitive data behind NPM, it's probably a good idea to use a certificate.\nNPMplus also supports DNS authentication for if you're not running your site facing the internet, or if you just want a wildcard certificate.", + "help-title": "TLS Certificates", + "other-certificate": "Certificate", + "other-certificate-key": "Certificate Key", + "other-intermediate-certificate": "Intermediate Certificate", + "reachability-404": "There is a server found at this domain but it does not seem to be NPMplus. Please make sure your domain points to the IP where your NPMplus instance is running.", + "reachability-failed-to-check": "Failed to check the reachability due to a communication error with site24x7.com.", + "reachability-failed-to-reach-api": "Communication with the API failed, is NPMplus running correctly?", + "reachability-info": "Test whether the domains are reachable from the public internet using Site24x7. This is not necessary when using the DNS Challenge.", + "reachability-not-resolved": "There is no server available at this domain. Please make sure your domain exists and points to the IP where your NPMplus instance is running and if necessary port 80 is forwarded in your router.", + "reachability-ok": "Your server is reachable and creating certificates should be possible.", + "reachability-other": "There is a server found at this domain but it returned an unexpected status code {code}. Is it the NPMplus server? Please make sure your domain points to the IP where your NPMplus instance is running.", + "reachability-title": "Test Server Reachability", + "reachability-wrong-data": "There is a server found at this domain but it returned an unexpected data. Is it the NPMplus server? Please make sure your domain points to the IP where your NPMplus instance is running.", + "renew-title": "Renew Certificate", + "search": "Search Certificate…", + "test-reachability": "Test Server Reachability", + "title": "TLS Certificates" }, - "menu": { - "dashboard": "Dashboard", - "hosts": "Hosts" + "dashboard": { + "title": "Hi {name}" + }, + "dead-hosts": { + "add": "Add 404 Host", + "delete": "Delete 404 Host", + "delete-confirm": "Are you sure you want to delete this 404 Host?", + "empty": "There are no 404 Hosts", + "form-title": "{id, select, undefined{New} other{Edit}} 404 Host", + "help-content": "A 404 Host is simply a host setup that shows a 404 page.\nThis can be useful when your domain is listed in search engines and you want to provide a nicer error page or specifically to tell the search indexers that the domain pages no longer exist.\nAnother benefit of having this host is to track the logs for hits to it and view the referrers.", + "help-title": "What is a 404 Host?", + "search": "Search Host…", + "title": "404 Hosts" }, "footer": { - "repo": "Repository on GitHub", "copy-npm": " - © 2024 jc21.com NPM", "copy-npmplus": " - and © 2024 ZoeyVid NPMplus", "license": " - MIT-License", + "repo": "Repository on GitHub", "theme": " - Theme by Tabler v0.0.31" }, - "dashboard": { - "title": "Hi {name}" - }, - "all-hosts": { - "empty-subtitle": "{manage, select, true{Why don't you create one?} other{And you don't have permission to create one.}}", - "details": "Details", - "force-https": "Force HTTPS", - "enable-brotli": "Enable Brotli", - "domain-names": "Domain Names", - "cert-provider": "Certificate Provider", - "enable-modsec": "Enable ModSecurity", - "enable-crs": "Enable CoreRuleSet (Requires ModSecurity)", - "tls-certificate": "TLS Certificate", - "none": "None", - "new-cert": "Request a new TLS Certificate", - "with-certbot": "with Certbot", - "no-tls": "This host will not use HTTPS", - "advanced": "Advanced", - "advanced-warning": "Enter your custom Nginx configuration here at your own risk!", - "advanced-config": "Custom Nginx Configuration", - "advanced-config-var-headline": "These proxy details are available as nginx variables:", - "advanced-config-header-info": "Please note, adding a location '/' will overwrite the proxy configuration", - "enable-hsts": "Enable HSTS and security headers", - "enable-http3": "Enable HTTP/3-Quic", - "locations": "Custom locations" - }, "locations": { - "new_location": "Add location", - "path": "/path", + "delete": "Delete", "location_label": "Define location", - "delete": "Delete" + "new_location": "Add location", + "path": "/path" }, - "tls": { - "letsencrypt": "Certbot", - "certbot": "Certbot", - "other": "Custom", - "none": "HTTP only", - "certbot-email": "Email Address for Certbot", - "certbot-agree": "I Agree to the Let's Encrypt Terms of Service / ToS of custom set CA", - "delete-tls": "The TLS certificates attached will NOT be removed, they will need to be removed manually.", - "hosts-warning": "These domains must be already configured to point to this installation", - "no-wildcard-without-dns": "Cannot request Certificate for wildcard domains when not using DNS challenge", - "dns-challenge": "Use a DNS Challenge", - "certbot-warning": "This section requires some knowledge about Certbot and its DNS plugins. Please consult the respective plugins documentation.", - "dns-provider": "DNS Provider", - "credentials-file-content": "Credentials File Content", - "credentials-file-content-info": "This plugin requires a configuration file containing an API token or other credentials to your provider", - "stored-as-plaintext-info": "This data will be stored as plaintext in the database and in a file!", - "propagation-seconds": "Propagation Seconds", - "propagation-seconds-info": "Leave empty to use the plugins default value. Number of seconds to wait for DNS propagation.", - "processing-info": "Processing... This might take a few minutes.", - "passphrase-protection-support-info": "Key files protected with a passphrase are not supported." + "login": { + "title": "Login to your account" + }, + "main": { + "app": "NPMplus", + "logged-in": "You are logged in as {name}", + "sign-in-as": "Sign back in as {name}", + "unknown-user": "Unknown User", + "version": "0.0.0", + "welcome": "Welcome to NPMplus" + }, + "menu": { + "dashboard": "Dashboard", + "hosts": "Hosts" }, "proxy-hosts": { - "title": "Proxy Hosts", - "empty": "There are no Proxy Hosts", + "access-list": "Access List", "add": "Add Proxy Host", + "allow-websocket-upgrade": "Websockets Support", + "custom-forward-host-help": "Add a path for sub-folder forwarding.\nExample: 203.0.113.25/path/", + "delete": "Delete Proxy Host", + "delete-confirm": "Are you sure you want to delete the Proxy host for: {domains}?", + "empty": "There are no Proxy Hosts", "form-title": "{id, select, undefined{New} other{Edit}} Proxy Host", - "forward-scheme": "Scheme", "forward-host": "Forward Hostname / IP", "forward-port": "Forward Port", - "delete": "Delete Proxy Host", - "delete-confirm": "Are you sure you want to delete the Proxy host for: {domains}?", - "help-title": "What is a Proxy Host?", + "forward-scheme": "Scheme", "help-content": "A Proxy Host is the incoming endpoint for a web service that you want to forward.\nIt provides optional TLS termination for your service that might not have TLS support built in.\nProxy Hosts are the most common use for the NPMplus.", - "access-list": "Access List", - "allow-websocket-upgrade": "Websockets Support", - "custom-forward-host-help": "Add a path for sub-folder forwarding.\nExample: 203.0.113.25/path/", - "search": "Search Host…" + "help-title": "What is a Proxy Host?", + "search": "Search Host…", + "title": "Proxy Hosts" }, "redirection-hosts": { - "title": "Redirection Hosts", - "empty": "There are no Redirection Hosts", "add": "Add Redirection Host", - "form-title": "{id, select, undefined{New} other{Edit}} Redirection Host", - "forward-scheme": "Scheme", - "forward-http-status-code": "HTTP Code", - "forward-domain": "Forward Domain", - "preserve-path": "Preserve Path", "delete": "Delete Redirection Host", "delete-confirm": "Are you sure you want to delete the Redirection host for: {domains}?", - "help-title": "What is a Redirection Host?", + "empty": "There are no Redirection Hosts", + "form-title": "{id, select, undefined{New} other{Edit}} Redirection Host", + "forward-domain": "Forward Domain", + "forward-http-status-code": "HTTP Code", + "forward-scheme": "Scheme", "help-content": "A Redirection Host will redirect requests from the incoming domain and push the viewer to another domain.\nThe most common reason to use this type of host is when your website changes domains but you still have search engine or referrer links pointing to the old domain.", - "search": "Search Host…" + "help-title": "What is a Redirection Host?", + "preserve-path": "Preserve Path", + "search": "Search Host…", + "title": "Redirection Hosts" }, - "dead-hosts": { - "title": "404 Hosts", - "empty": "There are no 404 Hosts", - "add": "Add 404 Host", - "form-title": "{id, select, undefined{New} other{Edit}} 404 Host", - "delete": "Delete 404 Host", - "delete-confirm": "Are you sure you want to delete this 404 Host?", - "help-title": "What is a 404 Host?", - "help-content": "A 404 Host is simply a host setup that shows a 404 page.\nThis can be useful when your domain is listed in search engines and you want to provide a nicer error page or specifically to tell the search indexers that the domain pages no longer exist.\nAnother benefit of having this host is to track the logs for hits to it and view the referrers.", - "search": "Search Host…" + "roles": { + "admin": "Administrator", + "title": "Roles", + "user": "User" + }, + "settings": { + "default-site": "Default Site", + "default-site-404": "404 Page", + "default-site-444": "Drop connection - only allows certbot dns-challenge", + "default-site-congratulations": "Congratulations Page", + "default-site-description": "What to show when Nginx is hit with an unknown Host", + "default-site-html": "Custom Page", + "default-site-redirect": "Redirect", + "title": "Settings" + }, + "str": { + "access": "Access", + "all": "All", + "any": "Any", + "cancel": "Cancel", + "choose-file": "Choose file", + "close": "Close", + "created-on": "Created: {date}", + "delete": "Delete", + "destination": "Destination", + "disable": "Disable", + "disabled": "Disabled", + "edit": "Edit", + "email": "Email", + "email-address": "Email address", + "enable": "Enable", + "expires": "Expires", + "name": "Name", + "offline": "Offline", + "online": "Online", + "password": "Password", + "please-wait": "Please wait...", + "public": "Public", + "roles": "Roles", + "save": "Save", + "sign-in": "Sign in", + "sign-out": "Sign out", + "source": "Source", + "status": "Status", + "sure": "Yes I'm Sure", + "tls": "TLS", + "try-again": "Try again", + "unknown": "Unknown", + "username": "Username", + "value": "Value" }, "streams": { - "title": "Streams", - "empty": "There are no Streams", "add": "Add Stream", + "delete": "Delete Stream", + "delete-confirm": "Are you sure you want to delete this Stream?", + "empty": "There are no Streams", "form-title": "{id, select, undefined{New} other{Edit}} Stream", - "incoming-port": "Incoming Port", + "forward-type-error": "At least one type of protocol must be enabled", "forwarding-host": "Forward Host", "forwarding-port": "Forward Port", - "tcp-forwarding": "TCP Forwarding", - "udp-forwarding": "UDP Forwarding", - "forward-type-error": "At least one type of protocol must be enabled", + "help-content": "A relatively new feature for Nginx, a Stream will serve to forward TCP/UDP traffic directly to another computer on the network.\nIf you're running game servers, FTP or SSH servers this can come in handy.", + "help-title": "What is a Stream?", + "incoming-port": "Incoming Port", "protocol": "Protocol", + "search": "Search Incoming Port…", "tcp": "TCP", + "tcp-forwarding": "TCP Forwarding", + "title": "Streams", "udp": "UDP", - "delete": "Delete Stream", - "delete-confirm": "Are you sure you want to delete this Stream?", - "help-title": "What is a Stream?", - "help-content": "A relatively new feature for Nginx, a Stream will serve to forward TCP/UDP traffic directly to another computer on the network.\nIf you're running game servers, FTP or SSH servers this can come in handy.", - "search": "Search Incoming Port…" - }, - "certificates": { - "title": "TLS Certificates", - "empty": "There are no TLS Certificates", - "add": "Add TLS Certificate", - "form-title": "Add {provider, select, letsencrypt{Certbot} other{Custom}} Certificate", - "delete": "Delete TLS Certificate", - "delete-confirm": "Are you sure you want to delete this TLS Certificate? Any hosts using it will need to be updated later.", - "help-title": "TLS Certificates", - "help-content": "TLS certificates (previously known as SSL Certificates) are a form of encryption key which allows your site to be encrypted for the end user.\nNPMplus uses by default a service called Let's Encrypt to issue TLS certificates for free.\nIf you have any sort of personal information, passwords, or sensitive data behind NPM, it's probably a good idea to use a certificate.\nNPMplus also supports DNS authentication for if you're not running your site facing the internet, or if you just want a wildcard certificate.", - "other-certificate": "Certificate", - "other-certificate-key": "Certificate Key", - "other-intermediate-certificate": "Intermediate Certificate", - "force-renew": "Renew Now", - "test-reachability": "Test Server Reachability", - "reachability-title": "Test Server Reachability", - "reachability-info": "Test whether the domains are reachable from the public internet using Site24x7. This is not necessary when using the DNS Challenge.", - "reachability-failed-to-reach-api": "Communication with the API failed, is NPMplus running correctly?", - "reachability-failed-to-check": "Failed to check the reachability due to a communication error with site24x7.com.", - "reachability-ok": "Your server is reachable and creating certificates should be possible.", - "reachability-404": "There is a server found at this domain but it does not seem to be NPMplus. Please make sure your domain points to the IP where your NPMplus instance is running.", - "reachability-not-resolved": "There is no server available at this domain. Please make sure your domain exists and points to the IP where your NPMplus instance is running and if necessary port 80 is forwarded in your router.", - "reachability-wrong-data": "There is a server found at this domain but it returned an unexpected data. Is it the NPMplus server? Please make sure your domain points to the IP where your NPMplus instance is running.", - "reachability-other": "There is a server found at this domain but it returned an unexpected status code {code}. Is it the NPMplus server? Please make sure your domain points to the IP where your NPMplus instance is running.", - "download": "Download", - "renew-title": "Renew Certificate", - "search": "Search Certificate…" + "udp-forwarding": "UDP Forwarding" }, - "access-lists": { - "title": "Access Lists", - "empty": "There are no Access Lists", - "add": "Add Access List", - "form-title": "{id, select, undefined{New} other{Edit}} Access List", - "delete": "Delete Access List", - "delete-confirm": "Are you sure you want to delete this access list?", - "public": "Publicly Accessible", - "public-sub": "No Access Restrictions", - "help-title": "What is an Access List?", - "help-content": "Access Lists provide a blacklist or whitelist of specific client IP addresses along with authentication for the Proxy Hosts via Basic HTTP Authentication.\nYou can configure multiple client rules, usernames and passwords for a single Access List and then apply that to a Proxy Host.\nThis is most useful for forwarded web services that do not have authentication mechanisms built in or that you want to protect from access by unknown clients.", - "item-count": "{count} {count, select, 1{User} other{Users}}", - "client-count": "{count} {count, select, 1{Rule} other{Rules}}", - "proxy-host-count": "{count} {count, select, 1{Proxy Host} other{Proxy Hosts}}", - "delete-has-hosts": "This Access List is associated with {count} Proxy Hosts. They will become publicly available upon deletion.", - "details": "Details", - "authorization": "Authorization", - "access": "Access", - "satisfy": "Satisfy", - "satisfy-any": "Allow access if at least one authorization method succeeded", - "pass-auth": "Don't pass credentials to backend of host", - "access-add": "Add", - "auth-add": "Add", - "search": "Search Access…" + "tls": { + "certbot": "Certbot", + "certbot-agree": "I Agree to the Let's Encrypt Terms of Service / ToS of custom set CA", + "certbot-email": "Email Address for Certbot", + "certbot-warning": "This section requires some knowledge about Certbot and its DNS plugins. Please consult the respective plugins documentation.", + "credentials-file-content": "Credentials File Content", + "credentials-file-content-info": "This plugin requires a configuration file containing an API token or other credentials to your provider", + "delete-tls": "The TLS certificates attached will NOT be removed, they will need to be removed manually.", + "dns-challenge": "Use a DNS Challenge", + "dns-provider": "DNS Provider", + "hosts-warning": "These domains must be already configured to point to this installation", + "letsencrypt": "Certbot", + "no-wildcard-without-dns": "Cannot request Certificate for wildcard domains when not using DNS challenge", + "none": "HTTP only", + "other": "Custom", + "passphrase-protection-support-info": "Key files protected with a passphrase are not supported.", + "processing-info": "Processing... This might take a few minutes.", + "propagation-seconds": "Propagation Seconds", + "propagation-seconds-info": "Leave empty to use the plugins default value. Number of seconds to wait for DNS propagation.", + "stored-as-plaintext-info": "This data will be stored as plaintext in the database and in a file!" }, "users": { - "title": "Users", - "default_error": "Default email address must be changed", "add": "Add User", - "nickname": "Nickname", - "full-name": "Full Name", - "edit-details": "Edit Details", + "admin-perms": "This user is an Administrator and some items cannot be altered", "change-password": "Change Password", - "edit-permissions": "Edit Permissions", - "sign-in-as": "Sign in as User", - "form-title": "{id, select, undefined{New} other{Edit}} User", + "confirm-password": "Confirm Password", + "current-password": "Current Password", + "default_error": "Default email address must be changed", "delete": "Delete {name, select, undefined{User} other{{name}}}", "delete-confirm": "Are you sure you want to delete {name}?", - "password-title": "Change Password{self, select, false{ for {name}} other{}}", - "current-password": "Current Password", + "edit-details": "Edit Details", + "edit-permissions": "Edit Permissions", + "form-title": "{id, select, undefined{New} other{Edit}} User", + "full-name": "Full Name", "new-password": "New Password", - "confirm-password": "Confirm Password", + "nickname": "Nickname", + "owned-by": "Owned by {name}", + "owned-by-deleted": "Deleted user", + "password-title": "Change Password{self, select, false{ for {name}} other{}}", + "perm-hidden": "Hidden", + "perm-manage": "Manage", + "perm-view": "View Only", "permissions-title": "Permissions for {name}", - "admin-perms": "This user is an Administrator and some items cannot be altered", "perms-visibility": "Item Visibility", - "perms-visibility-user": "Created Items Only", "perms-visibility-all": "All Items", - "perm-manage": "Manage", - "perm-view": "View Only", - "perm-hidden": "Hidden", - "search": "Search User…" - }, - "audit-log": { - "title": "Audit Log", - "empty": "There are no logs.", - "empty-subtitle": "As soon as you or another user changes something, history of those events will show up here.", - "proxy-host": "Proxy Host", - "redirection-host": "Redirection Host", - "dead-host": "404 Host", - "stream": "Stream", - "user": "User", - "certificate": "Certificate", - "access-list": "Access List", - "created": "Created {name}", - "updated": "Updated {name}", - "deleted": "Deleted {name}", - "enabled": "Enabled {name}", - "disabled": "Disabled {name}", - "renewed": "Renewed {name}", - "meta-title": "Details for Event", - "view-meta": "View Details", - "date": "Date", - "search": "Search Log…" - }, - "settings": { - "title": "Settings", - "default-site": "Default Site", - "default-site-description": "What to show when Nginx is hit with an unknown Host", - "default-site-congratulations": "Congratulations Page", - "default-site-404": "404 Page", - "default-site-444": "Drop connection - only allows certbot dns-challenge", - "default-site-html": "Custom Page", - "default-site-redirect": "Redirect" + "perms-visibility-user": "Created Items Only", + "search": "Search User…", + "sign-in-as": "Sign in as User", + "title": "Users" } } diff --git a/frontend/package.json b/frontend/package.json index 4ae5c5158..5d63c72c5 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -12,7 +12,7 @@ "backbone.marionette": "4.1.3", "copy-webpack-plugin": "5.1.2", "css-loader": "5.2.7", - "ejs-lint": "2.0.0", + "ejs-lint": "2.0.1", "ejs-loader": "0.4.1", "ejs-webpack-loader": "2.2.2", "file-loader": "6.2.0", diff --git a/rootfs/etc/certbot.ini b/rootfs/etc/certbot.ini index 881bb510c..ab7d9d461 100644 --- a/rootfs/etc/certbot.ini +++ b/rootfs/etc/certbot.ini @@ -1,6 +1,5 @@ new-key = true key-type = ecdsa -must-staple = true no-reuse-key = true rsa-key-size = 4096 elliptic-curve = secp384r1 diff --git a/rootfs/usr/local/bin/start.sh b/rootfs/usr/local/bin/start.sh index 0237bd082..cd9cd5e8f 100755 --- a/rootfs/usr/local/bin/start.sh +++ b/rootfs/usr/local/bin/start.sh @@ -78,6 +78,16 @@ if { [ -n "$ACME_EAB_KID" ] || [ -n "$ACME_EAB_HMAC_KEY" ]; } && { [ -z "$ACME_E sleep inf fi +if ! echo "$ACME_MUST_STAPLE" | grep -q "^true$\|^false$"; then + echo "ACME_MUST_STAPLE needs to be true or false." + sleep inf +fi + +if ! echo "$ACME_SERVER_TLS_VERIFY" | grep -q "^true$\|^false$"; then + echo "ACME_SERVER_TLS_VERIFY needs to be true or false." + sleep inf +fi + if ! echo "$PUID" | grep -q "^[0-9]\+$"; then echo "PUID needs to be a number." @@ -525,13 +535,15 @@ if [ -n "$(ls -A /data/ssl 2> /dev/null)" ]; then mv -vn /data/ssl/* /data/tls fi -find /data/tls/certbot/live ! -name "$(printf "*\n*")" -type f -name "*.pem" > tmp -while IFS= read -r cert -do +if [ -d /data/tls/certbot/live ] && [ -d /data/tls/certbot/archive ]; then + find /data/tls/certbot/live ! -name "$(printf "*\n*")" -type f -name "*.pem" > tmp + while IFS= read -r cert + do rm -vf "$cert" ln -s "$(find /data/tls/certbot/archive/"$(echo "$cert" | sed "s|/data/tls/certbot/live/\(npm-[0-9]\+/.*\).pem|\1|g")"*.pem | sort -r | head -n1 | sed "s|/data/tls/certbot/|../../|g")" "$cert" -done < tmp -rm tmp + done < tmp + rm tmp +fi if [ "$CLEAN" = "true" ]; then rm -vrf /data/letsencrypt-acme-challenge \ @@ -558,17 +570,19 @@ if [ "$CLEAN" = "true" ]; then rm -vf /data/tls/certbot/crs/*.pem rm -vf /data/tls/certbot/keys/*.pem - certs_in_use="$(find /data/tls/certbot/live -type l -name "*.pem" -exec readlink -f {} \;)" - export certs_in_use - # from: https://www.shellcheck.net/wiki/SC2044 - find /data/tls/certbot/archive ! -name "$(printf "*\n*")" -type f -name "*.pem" > tmp - while IFS= read -r archive - do + if [ -d /data/tls/certbot/live ] && [ -d /data/tls/certbot/archive ]; then + certs_in_use="$(find /data/tls/certbot/live -type l -name "*.pem" -exec readlink -f {} \;)" + export certs_in_use + # from: https://www.shellcheck.net/wiki/SC2044 + find /data/tls/certbot/archive ! -name "$(printf "*\n*")" -type f -name "*.pem" > tmp + while IFS= read -r archive + do if ! echo "$certs_in_use" | grep -q "$archive"; then - rm -vf "$archive" + rm -vf "$archive" fi - done < tmp - rm tmp + done < tmp + rm tmp + fi fi if [ -s "$DB_SQLITE_FILE" ]; then