add multi language support through @lateautumn233/dep updates

Signed-off-by: Zoey <zoey@z0ey.de>
Co-Authored-By: 秋秋 <lateautumn233@foxmail.com>
This commit is contained in:
Zoey 2024-10-29 11:56:52 +01:00
parent 818b92dad7
commit caa72418f1
27 changed files with 384 additions and 396 deletions

View file

@ -75,9 +75,9 @@ FROM zoeyvid/nginx-quic:350-python
SHELL ["/bin/ash", "-eo", "pipefail", "-c"]
COPY rootfs /
COPY --from=zoeyvid/certbot-docker:59 /usr/local /usr/local
COPY --from=zoeyvid/curl-quic:420 /usr/local/bin/curl /usr/local/bin/curl
COPY --from=zoeyvid/curl-quic:423 /usr/local/bin/curl /usr/local/bin/curl
ARG CRS_VER=v4.7.0
ARG CRS_VER=v4.8.0
RUN apk upgrade --no-cache -a && \
apk add --no-cache ca-certificates tzdata tini \
nodejs \

View file

@ -85,6 +85,7 @@ so that the barrier for entry here is low.
- 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.

View file

@ -2,7 +2,7 @@ const UserModel = require('../models/user');
let cache = {
User: new UserModel.Model(),
locale: 'en',
locale: navigator.languages[0].toLowerCase(),
version: null
};

View file

@ -1,5 +1,4 @@
const Cache = ('./cache');
const messages = require('../i18n/messages.json');
const Cache = require('./cache');
/**
* @param {String} namespace
@ -8,16 +7,11 @@ const messages = require('../i18n/messages.json');
*/
module.exports = function (namespace, key, data) {
let locale = Cache.locale;
// check that the locale exists
if (typeof messages[locale] === 'undefined') {
locale = 'en';
}
messages = require('../i18n/en-lang.json');
if (typeof messages[locale][namespace] !== 'undefined' && typeof messages[locale][namespace][key] !== 'undefined') {
return messages[locale][namespace][key](data);
} else if (locale !== 'en' && typeof messages['en'][namespace] !== 'undefined' && typeof messages['en'][namespace][key] !== 'undefined') {
return messages['en'][namespace][key](data);
if (typeof messages[namespace] !== 'undefined' && typeof messages[namespace][key] !== 'undefined') {
return messages[namespace][key](data);
} else {
return `(MISSING: ${namespace}.${key})`;
}
return '(MISSING: ' + namespace + '/' + key + ')';
};

View file

@ -3,16 +3,16 @@
<div class="title">
<i class="fe fe-shield text-success"></i> <%- i18n('all-hosts', 'new-cert') %>
</div>
<span class="description"><%- i18n('all-hosts', 'with-le') %></span>
<span class="description"><%- i18n('all-hosts', 'with-certbot') %></span>
<% } else if (id > 0) { %>
<div class="title">
<i class="fe fe-shield text-pink"></i> <%- provider === 'other' ? nice_name : domain_names.join(', ') %>
</div>
<span class="description"><%- i18n('ssl', provider) %> &ndash; Expires: <%- formatDbDate(expires_on, 'Do MMMM YYYY, h:mm a') %></span>
<span class="description"><%- i18n('tls', provider) %> &ndash; Expires: <%- formatDbDate(expires_on, 'Do MMMM YYYY, h:mm a') %></span>
<% } else { %>
<div class="title">
<i class="fe fe-shield-off text-danger"></i> <%- i18n('all-hosts', 'none') %>
</div>
<span class="description"><%- i18n('all-hosts', 'no-ssl') %></span>
<span class="description"><%- i18n('all-hosts', 'no-tls') %></span>
<% } %>
</div>

View file

@ -7,7 +7,7 @@
<div class="alert alert-danger mb-0 rounded-0" id="le-error-info" role="alert"></div>
<div class="text-center loader-content">
<div class="loader mx-auto my-6"></div>
<p><%- i18n('ssl', 'processing-info') %></p>
<p><%- i18n('tls', 'processing-info') %></p>
</div>
<form class="non-loader-content">
<div class="row">
@ -16,7 +16,7 @@
<div class="form-group">
<label class="form-label"><%- i18n('all-hosts', 'domain-names') %> <span class="form-required">*</span></label>
<input type="text" name="domain_names" class="form-control" id="input-domains" value="<%- domain_names.join(',') %>" required>
<div class="text-blue"><i class="fe fe-alert-triangle"></i> <%- i18n('ssl', 'hosts-warning') %></div>
<div class="text-blue"><i class="fe fe-alert-triangle"></i> <%- i18n('tls', 'hosts-warning') %></div>
</div>
<div class="mb-3 test-domains-container">
<button type="button" class="btn btn-secondary test-domains col-sm-12"><%- i18n('certificates', 'test-reachability') %></button>
@ -29,7 +29,7 @@
<!---
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label class="form-label"><%- i18n('ssl', 'letsencrypt-email') %> <span class="form-required">*</span></label>
<label class="form-label"><%- i18n('tls', 'certbot-email') %> <span class="form-required">*</span></label>
<input name="meta[letsencrypt_email]" type="email" class="form-control" placeholder="" value="<%- getLetsencryptEmail() %>" required>
</div>
</div>
@ -47,19 +47,19 @@
<%- getUseDnsChallenge() ? 'checked' : '' %>
>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%= i18n('ssl', 'dns-challenge') %></span>
<span class="custom-switch-description"><%= i18n('tls', 'dns-challenge') %></span>
</label>
</div>
</div>
<div class="col-sm-12 col-md-12">
<fieldset class="form-fieldset dns-challenge">
<div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('ssl', 'certbot-warning') %></div>
<div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('tls', 'certbot-warning') %></div>
<!-- Certbot DNS plugin selection -->
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label class="form-label"><%- i18n('ssl', 'dns-provider') %> <span class="form-required">*</span></label>
<label class="form-label"><%- i18n('tls', 'dns-provider') %> <span class="form-required">*</span></label>
<select
name="meta[dns_provider]"
id="dns_provider"
@ -86,7 +86,7 @@
<div class="row credentials-file-content">
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label class="form-label"><%- i18n('ssl', 'credentials-file-content') %> <span class="form-required">*</span></label>
<label class="form-label"><%- i18n('tls', 'credentials-file-content') %> <span class="form-required">*</span></label>
<textarea
name="meta[dns_provider_credentials]"
class="form-control text-monospace"
@ -94,11 +94,11 @@
><%- getDnsProviderCredentials() %></textarea>
<div class="text-secondary small">
<i class="fe fe-info"></i>
<%= i18n('ssl', 'credentials-file-content-info') %>
<%= i18n('tls', 'credentials-file-content-info') %>
</div>
<div class="text-red small">
<i class="fe fe-alert-triangle"></i>
<%= i18n('ssl', 'stored-as-plaintext-info') %>
<%= i18n('tls', 'stored-as-plaintext-info') %>
</div>
</div>
</div>
@ -109,7 +109,7 @@
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="form-group mb-0">
<label class="form-label"><%- i18n('ssl', 'propagation-seconds') %></label>
<label class="form-label"><%- i18n('tls', 'propagation-seconds') %></label>
<input
type="number"
min="0"
@ -120,7 +120,7 @@
>
<div class="text-secondary small">
<i class="fe fe-info"></i>
<%= i18n('ssl', 'propagation-seconds-info') %>
<%= i18n('tls', 'propagation-seconds-info') %>
</div>
</div>
</div>
@ -134,14 +134,14 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="meta[letsencrypt_agree]" value="1" required<%- getLetsencryptAgree() ? ' checked' : '' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%= i18n('ssl', 'letsencrypt-agree', {url: 'https://letsencrypt.org/repository/'}) %> <span class="form-required">*</span></span>
<span class="custom-switch-description"><%= i18n('tls', 'certbot-agree', {url: 'https://letsencrypt.org/repository/'}) %> <span class="form-required">*</span></span>
</label>
</div>
</div>
<% } else if (provider === 'other') { %>
<!-- Other -->
<div class="col-sm-12 col-md-12">
<div class="text-blue mb-4"><%= i18n('ssl', 'passphrase-protection-support-info') %></div>
<div class="text-blue mb-4"><%= i18n('tls', 'passphrase-protection-support-info') %></div>
</div>
<div class="col-sm-12 col-md-12">
<div class="form-group">

View file

@ -106,7 +106,7 @@ module.exports = Mn.View.extend({
}
if (domain_err) {
alert(i18n('ssl', 'no-wildcard-without-dns'));
alert(i18n('tls', 'no-wildcard-without-dns'));
return;
}

View file

@ -28,7 +28,7 @@
</div>
</td>
<td>
<%- i18n('ssl', provider) %><% if (meta.dns_provider) { %> - <%- dns_providers[meta.dns_provider].name %><% } %>
<%- i18n('tls', provider) %><% if (meta.dns_provider) { %> - <%- dns_providers[meta.dns_provider].name %><% } %>
</td>
<td class="<%- isExpired() ? 'text-danger' : '' %>">
<%- formatDbDate(expires_on, 'Do MMMM YYYY, h:mm a') %>

View file

@ -18,8 +18,8 @@
<%- i18n('certificates', 'add') %>
</button>
<div class="dropdown-menu">
<a class="dropdown-item add-item" data-cert="letsencrypt" href="#"><%- i18n('ssl', 'letsencrypt') %></a>
<a class="dropdown-item add-item" data-cert="other" href="#"><%- i18n('ssl', 'other') %></a>
<a class="dropdown-item add-item" data-cert="letsencrypt" href="#"><%- i18n('tls', 'certbot') %></a>
<a class="dropdown-item add-item" data-cert="other" href="#"><%- i18n('tls', 'other') %></a>
</div>
</div>
<% } %>

View file

@ -10,7 +10,7 @@
<%= i18n('dead-hosts', 'delete-confirm', {domains: domain_names.join(', ').toHtmlEntities()}) %>
<% if (certificate_id) { %>
<br><br>
<%- i18n('ssl', 'delete-ssl') %>
<%- i18n('tls', 'delete-tls') %>
<% } %>
</div>
</div>

View file

@ -30,7 +30,7 @@
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label class="form-label"><%- i18n('all-hosts', 'ssl-certificate') %></label>
<label class="form-label"><%- i18n('all-hosts', 'tls-certificate') %></label>
<select name="certificate_id" class="form-control custom-select" placeholder="<%- i18n('all-hosts', 'none') %>">
<option selected value="0" data-data="{&quot;id&quot;:0}" <%- certificate_id ? '' : 'selected' %>><%- i18n('all-hosts', 'none') %></option>
<option selected value="new" data-data="{&quot;id&quot;:&quot;new&quot;}"><%- i18n('all-hosts', 'new-cert') %></option>
@ -42,7 +42,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="ssl_forced" value="1"<%- ssl_forced ? ' checked' : '' %><%- certificate_id ? '' : ' disabled' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'force-ssl') %></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'force-https') %></span>
</label>
</div>
</div>
@ -51,7 +51,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="http2_support" value="1"<%- http2_support ? ' checked' : '' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'http2-support') %></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'enable-brotli') %></span>
</label>
</div>
</div>
@ -60,7 +60,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="hsts_enabled" value="1"<%- hsts_enabled ? ' checked' : '' %><%- certificate_id && ssl_forced ? '' : ' disabled' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'hsts-enabled') %> <a href="https://github.com/ZoeyVid/NPMplus/blob/develop/rootfs/usr/local/nginx/conf/conf.d/include/hsts.conf" target="_blank"><i class="fe fe-help-circle"></i></a></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'enable-hsts') %> <a href="https://github.com/ZoeyVid/NPMplus/blob/develop/rootfs/usr/local/nginx/conf/conf.d/include/hsts.conf" target="_blank"><i class="fe fe-help-circle"></i></a></span>
</label>
</div>
</div>
@ -69,7 +69,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="hsts_subdomains" value="1"<%- hsts_subdomains ? ' checked' : '' %><%- certificate_id ? '' : ' disabled' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'hsts-subdomains') %></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'enable-http3') %></span>
</label>
</div>
</div>
@ -86,19 +86,19 @@
<%- getUseDnsChallenge() ? 'checked' : '' %>
>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%= i18n('ssl', 'dns-challenge') %></span>
<span class="custom-switch-description"><%= i18n('tls', 'dns-challenge') %></span>
</label>
</div>
</div>
<div class="col-sm-12 col-md-12 letsencrypt">
<fieldset class="form-fieldset dns-challenge">
<div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('ssl', 'certbot-warning') %></div>
<div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('tls', 'certbot-warning') %></div>
<!-- Certbot DNS plugin selection -->
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label class="form-label"><%- i18n('ssl', 'dns-provider') %> <span class="form-required">*</span></label>
<label class="form-label"><%- i18n('tls', 'dns-provider') %> <span class="form-required">*</span></label>
<select
name="meta[dns_provider]"
id="dns_provider"
@ -125,7 +125,7 @@
<div class="row credentials-file-content">
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label class="form-label"><%- i18n('ssl', 'credentials-file-content') %> <span class="form-required">*</span></label>
<label class="form-label"><%- i18n('tls', 'credentials-file-content') %> <span class="form-required">*</span></label>
<textarea
name="meta[dns_provider_credentials]"
class="form-control text-monospace"
@ -133,11 +133,11 @@
><%- getDnsProviderCredentials() %></textarea>
<div class="text-secondary small">
<i class="fe fe-info"></i>
<%= i18n('ssl', 'credentials-file-content-info') %>
<%= i18n('tls', 'credentials-file-content-info') %>
</div>
<div class="text-red small">
<i class="fe fe-alert-triangle"></i>
<%= i18n('ssl', 'stored-as-plaintext-info') %>
<%= i18n('tls', 'stored-as-plaintext-info') %>
</div>
</div>
</div>
@ -148,7 +148,7 @@
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="form-group mb-0">
<label class="form-label"><%- i18n('ssl', 'propagation-seconds') %></label>
<label class="form-label"><%- i18n('tls', 'propagation-seconds') %></label>
<input
type="number"
min="0"
@ -159,7 +159,7 @@
>
<div class="text-secondary small">
<i class="fe fe-info"></i>
<%= i18n('ssl', 'propagation-seconds-info') %>
<%= i18n('tls', 'propagation-seconds-info') %>
</div>
</div>
</div>
@ -172,7 +172,7 @@
<!---
<div class="col-sm-12 col-md-12 letsencrypt">
<div class="form-group">
<label class="form-label"><%- i18n('ssl', 'letsencrypt-email') %> <span class="form-required">*</span></label>
<label class="form-label"><%- i18n('tls', 'certbot-email') %> <span class="form-required">*</span></label>
<input name="meta[letsencrypt_email]" type="email" class="form-control" placeholder="" value="<%- getLetsencryptEmail() %>" required disabled>
</div>
</div>
@ -182,7 +182,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="meta[letsencrypt_agree]" value="1" required disabled>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%= i18n('ssl', 'letsencrypt-agree', {url: 'https://letsencrypt.org/repository/'}) %> <span class="form-required">*</span></span>
<span class="custom-switch-description"><%= i18n('tls', 'certbot-agree', {url: 'https://letsencrypt.org/repository/'}) %> <span class="form-required">*</span></span>
</label>
</div>
</div>

View file

@ -149,7 +149,7 @@ module.exports = Mn.View.extend({
}
if (domain_err) {
alert(i18n('ssl', 'no-wildcard-without-dns'));
alert(i18n('tls', 'no-wildcard-without-dns'));
return;
}
} else {

View file

@ -23,7 +23,7 @@
</div>
</td>
<td>
<div><%- certificate ? i18n('ssl', certificate.provider) : i18n('ssl', 'none') %></div>
<div><%- certificate ? i18n('tls', certificate.provider) : i18n('tls', 'none') %></div>
</td>
<td>
<%

View file

@ -10,7 +10,7 @@
<%= i18n('proxy-hosts', 'delete-confirm', {domains: domain_names.join(', ').toHtmlEntities()}) %>
<% if (certificate_id) { %>
<br><br>
<%- i18n('ssl', 'delete-ssl') %>
<%- i18n('tls', 'delete-tls') %>
<% } %>
</div>
</div>

View file

@ -68,7 +68,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="block_exploits" value="1"<%- block_exploits ? ' checked' : '' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'block-exploits') %></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'enable-modsec') %></span>
</label>
</div>
</div>
@ -77,7 +77,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="caching_enabled" value="1"<%- caching_enabled ? ' checked' : '' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'caching-enabled') %></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'enable-crs') %></span>
</label>
</div>
</div>
@ -98,7 +98,7 @@
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label class="form-label"><%- i18n('all-hosts', 'ssl-certificate') %></label>
<label class="form-label"><%- i18n('all-hosts', 'tls-certificate') %></label>
<select name="certificate_id" class="form-control custom-select" placeholder="<%- i18n('all-hosts', 'none') %>">
<option selected value="0" data-data="{&quot;id&quot;:0}" <%- certificate_id ? '' : 'selected' %>><%- i18n('all-hosts', 'none') %></option>
<option selected value="new" data-data="{&quot;id&quot;:&quot;new&quot;}"><%- i18n('all-hosts', 'new-cert') %></option>
@ -110,7 +110,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="ssl_forced" value="1"<%- ssl_forced ? ' checked' : '' %><%- certificate_id ? '' : ' disabled' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'force-ssl') %></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'force-https') %></span>
</label>
</div>
</div>
@ -119,7 +119,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="http2_support" value="1"<%- http2_support ? ' checked' : '' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'http2-support') %></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'enable-brotli') %></span>
</label>
</div>
</div>
@ -128,7 +128,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="hsts_enabled" value="1"<%- hsts_enabled ? ' checked' : '' %><%- certificate_id && ssl_forced ? '' : ' disabled' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'hsts-enabled') %> <a href="https://github.com/ZoeyVid/NPMplus/blob/develop/rootfs/usr/local/nginx/conf/conf.d/include/hsts.conf" target="_blank"><i class="fe fe-help-circle"></i></a></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'enable-hsts') %> <a href="https://github.com/ZoeyVid/NPMplus/blob/develop/rootfs/usr/local/nginx/conf/conf.d/include/hsts.conf" target="_blank"><i class="fe fe-help-circle"></i></a></span>
</label>
</div>
</div>
@ -137,7 +137,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="hsts_subdomains" value="1"<%- hsts_subdomains ? ' checked' : '' %><%- certificate_id ? '' : ' disabled' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'hsts-subdomains') %></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'enable-http3') %></span>
</label>
</div>
</div>
@ -154,19 +154,19 @@
<%- getUseDnsChallenge() ? 'checked' : '' %>
>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%= i18n('ssl', 'dns-challenge') %></span>
<span class="custom-switch-description"><%= i18n('tls', 'dns-challenge') %></span>
</label>
</div>
</div>
<div class="col-sm-12 col-md-12 letsencrypt">
<fieldset class="form-fieldset dns-challenge">
<div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('ssl', 'certbot-warning') %></div>
<div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('tls', 'certbot-warning') %></div>
<!-- Certbot DNS plugin selection -->
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label class="form-label"><%- i18n('ssl', 'dns-provider') %> <span class="form-required">*</span></label>
<label class="form-label"><%- i18n('tls', 'dns-provider') %> <span class="form-required">*</span></label>
<select
name="meta[dns_provider]"
id="dns_provider"
@ -193,7 +193,7 @@
<div class="row credentials-file-content">
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label class="form-label"><%- i18n('ssl', 'credentials-file-content') %> <span class="form-required">*</span></label>
<label class="form-label"><%- i18n('tls', 'credentials-file-content') %> <span class="form-required">*</span></label>
<textarea
name="meta[dns_provider_credentials]"
class="form-control text-monospace"
@ -201,11 +201,11 @@
><%- getDnsProviderCredentials() %></textarea>
<div class="text-secondary small">
<i class="fe fe-info"></i>
<%= i18n('ssl', 'credentials-file-content-info') %>
<%= i18n('tls', 'credentials-file-content-info') %>
</div>
<div class="text-red small">
<i class="fe fe-alert-triangle"></i>
<%= i18n('ssl', 'stored-as-plaintext-info') %>
<%= i18n('tls', 'stored-as-plaintext-info') %>
</div>
</div>
</div>
@ -216,7 +216,7 @@
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="form-group mb-0">
<label class="form-label"><%- i18n('ssl', 'propagation-seconds') %></label>
<label class="form-label"><%- i18n('tls', 'propagation-seconds') %></label>
<input
type="number"
min="0"
@ -227,7 +227,7 @@
>
<div class="text-secondary small">
<i class="fe fe-info"></i>
<%= i18n('ssl', 'propagation-seconds-info') %>
<%= i18n('tls', 'propagation-seconds-info') %>
</div>
</div>
</div>
@ -240,7 +240,7 @@
<!---
<div class="col-sm-12 col-md-12 letsencrypt">
<div class="form-group">
<label class="form-label"><%- i18n('ssl', 'letsencrypt-email') %> <span class="form-required">*</span></label>
<label class="form-label"><%- i18n('tls', 'certbot-email') %> <span class="form-required">*</span></label>
<input name="meta[letsencrypt_email]" type="email" class="form-control" placeholder="" value="<%- getLetsencryptEmail() %>" required disabled>
</div>
</div>
@ -250,7 +250,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="meta[letsencrypt_agree]" value="1" required disabled>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%= i18n('ssl', 'letsencrypt-agree', {url: 'https://letsencrypt.org/repository/'}) %> <span class="form-required">*</span></span>
<span class="custom-switch-description"><%= i18n('tls', 'certbot-agree', {url: 'https://letsencrypt.org/repository/'}) %> <span class="form-required">*</span></span>
</label>
</div>
</div>

View file

@ -184,7 +184,7 @@ module.exports = Mn.View.extend({
}
if (domain_err) {
alert(i18n('ssl', 'no-wildcard-without-dns'));
alert(i18n('tls', 'no-wildcard-without-dns'));
return;
}
} else {

View file

@ -26,7 +26,7 @@
<div class="text-monospace"><%- forward_scheme %>://<%- forward_host %>:<%- forward_port %></div>
</td>
<td>
<div><%- certificate && certificate_id ? i18n('ssl', certificate.provider) : i18n('ssl', 'none') %></div>
<div><%- certificate && certificate_id ? i18n('tls', certificate.provider) : i18n('tls', 'none') %></div>
</td>
<td>
<div><%- access_list_id ? access_list.name : i18n('str', 'public') %></div>

View file

@ -10,7 +10,7 @@
<%= i18n('redirection-hosts', 'delete-confirm', {domains: domain_names.join(', ').toHtmlEntities()}) %>
<% if (certificate_id) { %>
<br><br>
<%- i18n('ssl', 'delete-ssl') %>
<%- i18n('tls', 'delete-tls') %>
<% } %>
</div>
</div>

View file

@ -66,7 +66,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="block_exploits" value="1"<%- block_exploits ? ' checked' : '' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'block-exploits') %></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'enable-modsec') %></span>
</label>
</div>
</div>
@ -79,7 +79,7 @@
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label class="form-label"><%- i18n('all-hosts', 'ssl-certificate') %></label>
<label class="form-label"><%- i18n('all-hosts', 'tls-certificate') %></label>
<select name="certificate_id" class="form-control custom-select" placeholder="<%- i18n('all-hosts', 'none') %>">
<option selected value="0" data-data="{&quot;id&quot;:0}" <%- certificate_id ? '' : 'selected' %>><%- i18n('all-hosts', 'none') %></option>
<option selected value="new" data-data="{&quot;id&quot;:&quot;new&quot;}"><%- i18n('all-hosts', 'new-cert') %></option>
@ -91,7 +91,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="ssl_forced" value="1"<%- ssl_forced ? ' checked' : '' %><%- certificate_id ? '' : ' disabled' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'force-ssl') %></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'force-https') %></span>
</label>
</div>
</div>
@ -100,7 +100,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="http2_support" value="1"<%- http2_support ? ' checked' : '' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'http2-support') %></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'enable-brotli') %></span>
</label>
</div>
</div>
@ -109,7 +109,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="hsts_enabled" value="1"<%- hsts_enabled ? ' checked' : '' %><%- certificate_id && ssl_forced ? '' : ' disabled' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'hsts-enabled') %> <a href="https://github.com/ZoeyVid/NPMplus/blob/develop/rootfs/usr/local/nginx/conf/conf.d/include/hsts.conf" target="_blank"><i class="fe fe-help-circle"></i></a></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'enable-hsts') %> <a href="https://github.com/ZoeyVid/NPMplus/blob/develop/rootfs/usr/local/nginx/conf/conf.d/include/hsts.conf" target="_blank"><i class="fe fe-help-circle"></i></a></span>
</label>
</div>
</div>
@ -118,7 +118,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="hsts_subdomains" value="1"<%- hsts_subdomains ? ' checked' : '' %><%- certificate_id ? '' : ' disabled' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'hsts-subdomains') %></span>
<span class="custom-switch-description"><%- i18n('all-hosts', 'enable-http3') %></span>
</label>
</div>
</div>
@ -135,19 +135,19 @@
<%- getUseDnsChallenge() ? 'checked' : '' %>
>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%= i18n('ssl', 'dns-challenge') %></span>
<span class="custom-switch-description"><%= i18n('tls', 'dns-challenge') %></span>
</label>
</div>
</div>
<div class="col-sm-12 col-md-12 letsencrypt">
<fieldset class="form-fieldset dns-challenge">
<div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('ssl', 'certbot-warning') %></div>
<div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('tls', 'certbot-warning') %></div>
<!-- Certbot DNS plugin selection -->
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label class="form-label"><%- i18n('ssl', 'dns-provider') %> <span class="form-required">*</span></label>
<label class="form-label"><%- i18n('tls', 'dns-provider') %> <span class="form-required">*</span></label>
<select
name="meta[dns_provider]"
id="dns_provider"
@ -174,7 +174,7 @@
<div class="row credentials-file-content">
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label class="form-label"><%- i18n('ssl', 'credentials-file-content') %> <span class="form-required">*</span></label>
<label class="form-label"><%- i18n('tls', 'credentials-file-content') %> <span class="form-required">*</span></label>
<textarea
name="meta[dns_provider_credentials]"
class="form-control text-monospace"
@ -182,11 +182,11 @@
><%- getDnsProviderCredentials() %></textarea>
<div class="text-secondary small">
<i class="fe fe-info"></i>
<%= i18n('ssl', 'credentials-file-content-info') %>
<%= i18n('tls', 'credentials-file-content-info') %>
</div>
<div class="text-red small">
<i class="fe fe-alert-triangle"></i>
<%= i18n('ssl', 'stored-as-plaintext-info') %>
<%= i18n('tls', 'stored-as-plaintext-info') %>
</div>
</div>
</div>
@ -197,7 +197,7 @@
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="form-group mb-0">
<label class="form-label"><%- i18n('ssl', 'propagation-seconds') %></label>
<label class="form-label"><%- i18n('tls', 'propagation-seconds') %></label>
<input
type="number"
min="0"
@ -208,7 +208,7 @@
>
<div class="text-secondary small">
<i class="fe fe-info"></i>
<%= i18n('ssl', 'propagation-seconds-info') %>
<%= i18n('tls', 'propagation-seconds-info') %>
</div>
</div>
</div>
@ -221,7 +221,7 @@
<!---
<div class="col-sm-12 col-md-12 letsencrypt">
<div class="form-group">
<label class="form-label"><%- i18n('ssl', 'letsencrypt-email') %> <span class="form-required">*</span></label>
<label class="form-label"><%- i18n('tls', 'certbot-email') %> <span class="form-required">*</span></label>
<input name="meta[letsencrypt_email]" type="email" class="form-control" placeholder="" value="<%- getLetsencryptEmail() %>" required disabled>
</div>
</div>
@ -231,7 +231,7 @@
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="meta[letsencrypt_agree]" value="1" required disabled>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%= i18n('ssl', 'letsencrypt-agree', {url: 'https://letsencrypt.org/repository/'}) %> <span class="form-required">*</span></span>
<span class="custom-switch-description"><%= i18n('tls', 'certbot-agree', {url: 'https://letsencrypt.org/repository/'}) %> <span class="form-required">*</span></span>
</label>
</div>
</div>

View file

@ -151,7 +151,7 @@ module.exports = Mn.View.extend({
}
if (domain_err) {
alert(i18n('ssl', 'no-wildcard-without-dns'));
alert(i18n('tls', 'no-wildcard-without-dns'));
return;
}
} else {

View file

@ -32,7 +32,7 @@
<div class="text-monospace"><%- forward_domain_name %></div>
</td>
<td>
<div><%- certificate ? i18n('ssl', certificate.provider) : i18n('ssl', 'none') %></div>
<div><%- certificate ? i18n('tls', certificate.provider) : i18n('tls', 'none') %></div>
</td>
<td>
<%

View file

@ -4,15 +4,16 @@
<div class="col-auto">
<ul class="list-inline list-inline-dots mb-0">
<li class="list-inline-item"><a href="#" onclick="toggleDarkMode()">Toggle Dark Mode</a></li>
<li class="list-inline-item"><a href="https://github.com/ZoeyVid/NPMplus" target="_blank"><%- i18n('footer', 'fork-me') %></a></li>
<li class="list-inline-item"><a href="https://github.com/ZoeyVid/NPMplus" target="_blank"><%- i18n('footer', 'repo') %></a></li>
</ul>
</div>
</div>
</div>
<div class="col-12 col-lg-auto mt-3 mt-lg-0 text-center">
<%- i18n('main', 'version', {version: getVersion()}) %>
<%= i18n('footer', 'copy', {url: 'https://jc21.com'}) %>
<%= i18n('footer', 'copyzv', {url: 'https://zoeyvid.de'}) %>
<%- i18n('main', 'version') %>
<%= i18n('footer', 'copy-npm', {url: 'https://jc21.com'}) %>
<%= i18n('footer', 'copy-npmplus', {url: 'https://zoeyvid.de'}) %>
<%= i18n('footer', 'license') %>
<%= i18n('footer', 'theme', {url: 'https://tabler.github.io'}) %>
</div>
</div>

View file

@ -0,0 +1,289 @@
{
"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": "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"
},
"login": {
"title": "Login to your account"
},
"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}"
},
"roles": {
"title": "Roles",
"admin": "Administrator",
"user": "User"
},
"menu": {
"dashboard": "Dashboard",
"hosts": "Hosts"
},
"footer": {
"repo": "Repository on GitHub",
"copy-npm": " - &copy; 2024 <a href=\"{url}\" target=\"_blank\">jc21.com</a> NPM",
"copy-npmplus": " - and &copy; 2024 <a href=\"{url}\" target=\"_blank\">ZoeyVid</a> NPMplus",
"license": " - MIT-License",
"theme": " - Theme by <a href=\"{url}\" target=\"_blank\">Tabler v0.0.31</a>"
},
"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",
"location_label": "Define location",
"delete": "Delete"
},
"tls": {
"certbot": "Certbot",
"other": "Custom",
"none": "HTTP only",
"certbot-email": "Email Address for Certbot",
"certbot-agree": "I Agree to the <a href=\"{url}\" target=\"_blank\">Let's Encrypt Terms of Service</a> / 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."
},
"proxy-hosts": {
"title": "Proxy Hosts",
"empty": "There are no Proxy Hosts",
"add": "Add Proxy Host",
"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: <strong>{domains}</strong>?",
"help-title": "What is a Proxy Host?",
"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…"
},
"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: <strong>{domains}</strong>?",
"help-title": "What is a Redirection Host?",
"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…"
},
"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…"
},
"streams": {
"title": "Streams",
"empty": "There are no Streams",
"add": "Add Stream",
"form-title": "{id, select, undefined{New} other{Edit}} Stream",
"incoming-port": "Incoming Port",
"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",
"protocol": "Protocol",
"tcp": "TCP",
"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…"
},
"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…"
},
"users": {
"title": "Users",
"default_error": "Default email address must be changed",
"add": "Add User",
"nickname": "Nickname",
"full-name": "Full Name",
"edit-details": "Edit Details",
"change-password": "Change Password",
"edit-permissions": "Edit Permissions",
"sign-in-as": "Sign in as User",
"form-title": "{id, select, undefined{New} other{Edit}} User",
"delete": "Delete {name, select, undefined{User} other{{name}}}",
"delete-confirm": "Are you sure you want to delete <strong>{name}</strong>?",
"password-title": "Change Password{self, select, false{ for {name}} other{}}",
"current-password": "Current Password",
"new-password": "New Password",
"confirm-password": "Confirm Password",
"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}",
"deleted": "Deleted {name}",
"enabled": "Enabled {name}",
"disabled": "Disabled {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"
}
}

View file

@ -1,297 +0,0 @@
{
"en": {
"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",
"ssl": "TLS",
"access": "Access",
"public": "Public",
"edit": "Edit",
"delete": "Delete",
"logs": "Logs",
"status": "Status",
"online": "Online",
"offline": "Offline",
"unknown": "Unknown",
"expires": "Expires",
"value": "Value",
"please-wait": "Please wait...",
"all": "All",
"any": "Any"
},
"login": {
"title": "Login to your account"
},
"main": {
"app": "NPMplus",
"version": "0.0.0",
"welcome": "Welcome to NPMplus",
"logged-in": "You are logged in as {name}",
"unknown-error": "Error loading stuff. Please reload the app.",
"unknown-user": "Unknown User",
"sign-in-as": "Sign back in as {name}"
},
"roles": {
"title": "Roles",
"admin": "Administrator",
"user": "User"
},
"menu": {
"dashboard": "Dashboard",
"hosts": "Hosts"
},
"footer": {
"fork-me": "Repository on GitHub",
"copy": "&copy; 2024 <a href=\"{url}\" target=\"_blank\">jc21.com</a> NPM",
"copyzv": "and &copy; 2024 <a href=\"{url}\" target=\"_blank\">ZoeyVid</a> NPMplus - MIT-License - ",
"theme": "Theme by <a href=\"{url}\" target=\"_blank\">Tabler v0.0.31</a>"
},
"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",
"enable-ssl": "Enable HTTPS",
"force-ssl": "Force HTTPS",
"http2-support": "Enable Brotli",
"domain-names": "Domain Names",
"cert-provider": "Certificate Provider",
"block-exploits": "Enable ModSecurity",
"caching-enabled": "Enable CoreRuleSet (Requires ModSecurity)",
"ssl-certificate": "TLS Certificate",
"none": "None",
"new-cert": "Request a new TLS Certificate",
"with-le": "with Certbot",
"no-ssl": "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",
"hsts-enabled": "Enable HSTS and security headers",
"hsts-subdomains": "Enable HTTP/3-Quic",
"locations": "Custom locations"
},
"locations": {
"new_location": "Add location",
"path": "/path",
"location_label": "Define location",
"delete": "Delete"
},
"ssl": {
"letsencrypt": "Certbot",
"other": "Custom",
"none": "HTTP only",
"letsencrypt-email": "Email Address for Certbot",
"letsencrypt-agree": "I Agree to the <a href=\"{url}\" target=\"_blank\">Let's Encrypt Terms of Service</a> / ToS of custom set CA",
"delete-ssl": "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",
"please-choose": "Please Choose...",
"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."
},
"proxy-hosts": {
"title": "Proxy Hosts",
"empty": "There are no Proxy Hosts",
"add": "Add Proxy Host",
"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: <strong>{domains}</strong>?",
"help-title": "What is a Proxy Host?",
"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",
"ignore-invalid-upstream-ssl": "Ignore Invalid TLS",
"custom-forward-host-help": "Add a path for sub-folder forwarding.\nExample: 203.0.113.25/path/",
"search": "Search Host…"
},
"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: <strong>{domains}</strong>?",
"help-title": "What is a Redirection Host?",
"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…"
},
"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…"
},
"streams": {
"title": "Streams",
"empty": "There are no Streams",
"add": "Add Stream",
"form-title": "{id, select, undefined{New} other{Edit}} Stream",
"incoming-port": "Incoming Port",
"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",
"protocol": "Protocol",
"tcp": "TCP",
"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.\nNPM 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.\nNPM 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 NPM 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 NPM 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 NPM 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 NPM server? Please make sure your domain points to the IP where your NPM instance is running.",
"reachability-other": "There is a server found at this domain but it returned an unexpected status code {code}. Is it the NPM server? Please make sure your domain points to the IP where your NPM instance is running.",
"download": "Download",
"renew-title": "Renew Certificate",
"search": "Search Certificate…"
},
"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…"
},
"users": {
"title": "Users",
"default_error": "Default email address must be changed",
"add": "Add User",
"nickname": "Nickname",
"full-name": "Full Name",
"edit-details": "Edit Details",
"change-password": "Change Password",
"edit-permissions": "Edit Permissions",
"sign-in-as": "Sign in as User",
"form-title": "{id, select, undefined{New} other{Edit}} User",
"delete": "Delete {name, select, undefined{User} other{{name}}}",
"delete-confirm": "Are you sure you want to delete <strong>{name}</strong>?",
"password-title": "Change Password{self, select, false{ for {name}} other{}}",
"current-password": "Current Password",
"new-password": "New Password",
"confirm-password": "Confirm Password",
"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"
}
}
}

View file

@ -9,7 +9,7 @@
<div class="text-center p-6">
<img src="/images/logo-text-vertical-grey.png" alt="Logo" />
<div class="text-center text-muted mt-5">
<%- i18n('main', 'version', {version: getVersion()}) %>
<%- i18n('main', 'version') %>
</div>
</div>
</div>

View file

@ -4,7 +4,7 @@
"description": "A beautiful interface for creating Nginx endpoints",
"main": "js/index.js",
"dependencies": {
"@babel/core": "7.25.9",
"@babel/core": "7.26.0",
"babel-core": "6.26.3",
"babel-loader": "8.4.1",
"babel-preset-env": "1.7.0",

View file

@ -50,7 +50,7 @@ module.exports = {
// other:
{
type: 'javascript/auto', // <= Set the module.type explicitly
test: /\bmessages\.json$/,
test: /-lang\.json$/,
loader: 'messageformat-loader',
options: {
biDiSupport: false,