mirror of
https://github.com/NginxProxyManager/nginx-proxy-manager.git
synced 2026-03-13 11:00:09 +00:00
Compare commits
229 Commits
v2.13.6
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4c8f0f1ce | ||
|
|
15896132ff | ||
|
|
604b32ffbf | ||
|
|
eb67b3bfb6 | ||
|
|
f1e95c9c52 | ||
|
|
d6e1d15996 | ||
|
|
99886f3111 | ||
|
|
6b2d9a77a3 | ||
|
|
d37ab95ed8 | ||
|
|
e869518dd1 | ||
|
|
37712ba2a4 | ||
|
|
a714b41fd6 | ||
|
|
b87bedc347 | ||
|
|
a62068275d | ||
|
|
c1d09eaceb | ||
|
|
9c509f30de | ||
|
|
c85b11ee33 | ||
|
|
cd5ef390b9 | ||
|
|
d49cab1c0e | ||
|
|
33b1a993ec | ||
|
|
67d40e186f | ||
|
|
52be66c43e | ||
|
|
ec46cabcd4 | ||
|
|
a7a9cc3acb | ||
|
|
020b3ebb33 | ||
|
|
c1c4baf389 | ||
|
|
672b5d6dd9 | ||
|
|
cd230b5878 | ||
|
|
a8f35062af | ||
|
|
da5955412d | ||
|
|
adb27fe67d | ||
|
|
d874af8692 | ||
|
|
0844dade98 | ||
|
|
71d59516e8 | ||
|
|
06e220e184 | ||
|
|
dc53647e76 | ||
|
|
4c04e89483 | ||
|
|
7241869a9e | ||
|
|
94f6191a21 | ||
|
|
cac52dd0ff | ||
|
|
906f177960 | ||
|
|
f52afced5d | ||
|
|
e8224ff0af | ||
|
|
a4fa83d0ce | ||
|
|
770716ebf8 | ||
|
|
f1067d3308 | ||
|
|
85c1a935ea | ||
|
|
51ef7f3b86 | ||
|
|
846b94f7e8 | ||
|
|
19e24c7e7e | ||
|
|
c1bc471dac | ||
|
|
608dc0b6bf | ||
|
|
0dbf268f37 | ||
|
|
c7437ddf8f | ||
|
|
627f43c729 | ||
|
|
fc4c5aac86 | ||
|
|
aff390f35d | ||
|
|
5f5a3870e4 | ||
|
|
40f363bd4f | ||
|
|
678fdd22c6 | ||
|
|
6c3cc83d66 | ||
|
|
5916fd5bee | ||
|
|
f105673904 | ||
|
|
a37d0b88d6 | ||
|
|
43bc2a743e | ||
|
|
269545256a | ||
|
|
e5df45e9ef | ||
|
|
5601dd14fc | ||
|
|
3e5655cfcd | ||
|
|
a90af83270 | ||
|
|
619a8e5acc | ||
|
|
6dcdefb57e | ||
|
|
787616010b | ||
|
|
5891c291d2 | ||
|
|
41a2a41e67 | ||
|
|
379099d7ed | ||
|
|
dbeab93c02 | ||
|
|
010cb562a0 | ||
|
|
7ff2fc1900 | ||
|
|
1c189a1888 | ||
|
|
f3c46487f6 | ||
|
|
fcca481d1b | ||
|
|
c59c237000 | ||
|
|
a62b6de9f2 | ||
|
|
d92cc953e1 | ||
|
|
1b6412688b | ||
|
|
1d14f72ba5 | ||
|
|
099243aff7 | ||
|
|
5fe12f69ba | ||
|
|
011191f645 | ||
|
|
eeab425ea4 | ||
|
|
13fbc53591 | ||
|
|
3f2aec7b86 | ||
|
|
09a3d65aa1 | ||
|
|
c910cf9512 | ||
|
|
304c51aae8 | ||
|
|
b552eb90ed | ||
|
|
b78ef9bcd3 | ||
|
|
7c67fafedf | ||
|
|
47b367d61e | ||
|
|
d19f5c1960 | ||
|
|
77662b4e7f | ||
|
|
c88de65d3a | ||
|
|
ac4efd2333 | ||
|
|
eab38d8934 | ||
|
|
4833dcbf3a | ||
|
|
c6fba1cbfe | ||
|
|
cdde543e8a | ||
|
|
0d62c26164 | ||
|
|
c3173d83b8 | ||
|
|
6ba40216cd | ||
|
|
3c54413752 | ||
|
|
65cf8ce583 | ||
|
|
a4bc8d5d21 | ||
|
|
2bcf5e91ce | ||
|
|
3e3d08b68f | ||
|
|
f90066822f | ||
|
|
bb4b5fb3aa | ||
|
|
8014f34195 | ||
|
|
4f8037ded2 | ||
|
|
e7a1f84e45 | ||
|
|
6f0931bed5 | ||
|
|
7f0c5d4364 | ||
|
|
60404b6f7e | ||
|
|
c2fddee2c7 | ||
|
|
b7402d47a0 | ||
|
|
f09876d31b | ||
|
|
8708a3bab8 | ||
|
|
218fadd168 | ||
|
|
9cf1d000c8 | ||
|
|
714bebbbc7 | ||
|
|
127008c9b5 | ||
|
|
7cc2bfbf6a | ||
|
|
de3b543d08 | ||
|
|
21f63e3db3 | ||
|
|
232b5b759a | ||
|
|
054742539f | ||
|
|
2b6a617599 | ||
|
|
187d21a0d5 | ||
|
|
c515815b0e | ||
|
|
3db02370fd | ||
|
|
4ad1af5576 | ||
|
|
a73d54fedc | ||
|
|
8c8005f817 | ||
|
|
83d993578b | ||
|
|
8532e7520f | ||
|
|
58d47cd69a | ||
|
|
bad3eac515 | ||
|
|
00b58f73f8 | ||
|
|
47981f0d56 | ||
|
|
38257859e2 | ||
|
|
a169e1131c | ||
|
|
a99cde9cd8 | ||
|
|
c69bd187af | ||
|
|
98fe622967 | ||
|
|
eddca3597d | ||
|
|
ed0b2306a2 | ||
|
|
17f6050de2 | ||
|
|
469d72a2f9 | ||
|
|
3ed3ec0001 | ||
|
|
24ff3c7b11 | ||
|
|
58dda941b8 | ||
|
|
f9f743499f | ||
|
|
534afe6067 | ||
|
|
9580903f5d | ||
|
|
df81c8425f | ||
|
|
b6f421c5fc | ||
|
|
c1ef3a3795 | ||
|
|
0aad939ccc | ||
|
|
7e092e265c | ||
|
|
cd01a2ee6b | ||
|
|
9e6720561a | ||
|
|
c50f0a144e | ||
|
|
2a9c1df3cb | ||
|
|
ef6391f22e | ||
|
|
0f46337710 | ||
|
|
1b84b8ace2 | ||
|
|
8ea8286cec | ||
|
|
7ca48f876b | ||
|
|
7c3c59c79f | ||
|
|
ef7f444404 | ||
|
|
f509e0bdba | ||
|
|
9b7af474bb | ||
|
|
28982b8bc2 | ||
|
|
19e654b998 | ||
|
|
eaf9f5ab1e | ||
|
|
4af0a968f0 | ||
|
|
df06eb6c2f | ||
|
|
74360cc9b3 | ||
|
|
16a301fc64 | ||
|
|
2d774124dc | ||
|
|
124737bbc6 | ||
|
|
d5d222ef2d | ||
|
|
b96e932c64 | ||
|
|
d09cb2884c | ||
|
|
71deabcc67 | ||
|
|
a78039b65f | ||
|
|
48acbd33ab | ||
|
|
32cabc0f83 | ||
|
|
03a82cd861 | ||
|
|
5f19f7125e | ||
|
|
8d35644190 | ||
|
|
ad2e4c8afe | ||
|
|
69f9031447 | ||
|
|
3308a308df | ||
|
|
59b0e75324 | ||
|
|
727bc944ea | ||
|
|
a0ef0d9048 | ||
|
|
d2e346c912 | ||
|
|
32a716b3a9 | ||
|
|
ef6918947c | ||
|
|
2deb5447d6 | ||
|
|
1bb29259ea | ||
|
|
fa20c7d8a4 | ||
|
|
4ed17fef01 | ||
|
|
fe316252f1 | ||
|
|
7747db994d | ||
|
|
9ffced265b | ||
|
|
50cf275328 | ||
|
|
7bcc34dea9 | ||
|
|
131e5fea4f | ||
|
|
4e412f18bb | ||
|
|
bb0a50eccb | ||
|
|
4185665570 | ||
|
|
9ea6fee3ce | ||
|
|
7ee9a3c9f0 | ||
|
|
afb196e5b6 | ||
|
|
0b464ac9fd | ||
|
|
c9f453714b |
104
.github/dependabot.yml
vendored
Normal file
104
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "npm"
|
||||||
|
directory: "/backend"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
groups:
|
||||||
|
dev-patch-updates:
|
||||||
|
dependency-type: "development"
|
||||||
|
update-types:
|
||||||
|
- "patch"
|
||||||
|
dev-minor-updates:
|
||||||
|
dependency-type: "development"
|
||||||
|
update-types:
|
||||||
|
- "minor"
|
||||||
|
prod-patch-updates:
|
||||||
|
dependency-type: "production"
|
||||||
|
update-types:
|
||||||
|
- "patch"
|
||||||
|
prod-minor-updates:
|
||||||
|
dependency-type: "production"
|
||||||
|
update-types:
|
||||||
|
- "minor"
|
||||||
|
|
||||||
|
- package-ecosystem: "npm"
|
||||||
|
directory: "/frontend"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
groups:
|
||||||
|
dev-patch-updates:
|
||||||
|
dependency-type: "development"
|
||||||
|
update-types:
|
||||||
|
- "patch"
|
||||||
|
dev-minor-updates:
|
||||||
|
dependency-type: "development"
|
||||||
|
update-types:
|
||||||
|
- "minor"
|
||||||
|
prod-patch-updates:
|
||||||
|
dependency-type: "production"
|
||||||
|
update-types:
|
||||||
|
- "patch"
|
||||||
|
prod-minor-updates:
|
||||||
|
dependency-type: "production"
|
||||||
|
update-types:
|
||||||
|
- "minor"
|
||||||
|
|
||||||
|
- package-ecosystem: "npm"
|
||||||
|
directory: "/docs"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
groups:
|
||||||
|
dev-patch-updates:
|
||||||
|
dependency-type: "development"
|
||||||
|
update-types:
|
||||||
|
- "patch"
|
||||||
|
dev-minor-updates:
|
||||||
|
dependency-type: "development"
|
||||||
|
update-types:
|
||||||
|
- "minor"
|
||||||
|
prod-patch-updates:
|
||||||
|
dependency-type: "production"
|
||||||
|
update-types:
|
||||||
|
- "patch"
|
||||||
|
prod-minor-updates:
|
||||||
|
dependency-type: "production"
|
||||||
|
update-types:
|
||||||
|
- "minor"
|
||||||
|
|
||||||
|
- package-ecosystem: "npm"
|
||||||
|
directory: "/test"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
groups:
|
||||||
|
dev-patch-updates:
|
||||||
|
dependency-type: "development"
|
||||||
|
update-types:
|
||||||
|
- "patch"
|
||||||
|
dev-minor-updates:
|
||||||
|
dependency-type: "development"
|
||||||
|
update-types:
|
||||||
|
- "minor"
|
||||||
|
prod-patch-updates:
|
||||||
|
dependency-type: "production"
|
||||||
|
update-types:
|
||||||
|
- "patch"
|
||||||
|
prod-minor-updates:
|
||||||
|
dependency-type: "production"
|
||||||
|
update-types:
|
||||||
|
- "minor"
|
||||||
|
|
||||||
|
- package-ecosystem: "docker"
|
||||||
|
directory: "/docker"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
groups:
|
||||||
|
updates:
|
||||||
|
update-types:
|
||||||
|
- "patch"
|
||||||
|
- "minor"
|
||||||
|
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
|||||||
stale:
|
stale:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v9
|
- uses: actions/stale@v10
|
||||||
with:
|
with:
|
||||||
stale-issue-label: 'stale'
|
stale-issue-label: 'stale'
|
||||||
stale-pr-label: 'stale'
|
stale-pr-label: 'stale'
|
||||||
|
|||||||
17
README.md
17
README.md
@@ -1,7 +1,7 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://nginxproxymanager.com/github.png">
|
<img src="https://nginxproxymanager.com/github.png">
|
||||||
<br><br>
|
<br><br>
|
||||||
<img src="https://img.shields.io/badge/version-2.13.6-green.svg?style=for-the-badge">
|
<img src="https://img.shields.io/badge/version-2.14.0-green.svg?style=for-the-badge">
|
||||||
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
|
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
|
||||||
<img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge">
|
<img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge">
|
||||||
</a>
|
</a>
|
||||||
@@ -36,6 +36,10 @@ so that the barrier for entry here is low.
|
|||||||
- Advanced Nginx configuration available for super users
|
- Advanced Nginx configuration available for super users
|
||||||
- User management, permissions and audit log
|
- User management, permissions and audit log
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
`armv7` is no longer supported in version 2.14+. This is due to Nodejs dropping support for armhf. Please
|
||||||
|
use the `2.13.7` image tag if this applies to you.
|
||||||
|
:::
|
||||||
|
|
||||||
## Hosting your home network
|
## Hosting your home network
|
||||||
|
|
||||||
@@ -43,16 +47,15 @@ I won't go in to too much detail here but here are the basics for someone new to
|
|||||||
|
|
||||||
1. Your home router will have a Port Forwarding section somewhere. Log in and find it
|
1. Your home router will have a Port Forwarding section somewhere. Log in and find it
|
||||||
2. Add port forwarding for port 80 and 443 to the server hosting this project
|
2. Add port forwarding for port 80 and 443 to the server hosting this project
|
||||||
3. Configure your domain name details to point to your home, either with a static ip or a service like DuckDNS or [Amazon Route53](https://github.com/jc21/route53-ddns)
|
3. Configure your domain name details to point to your home, either with a static ip or a service like
|
||||||
|
- DuckDNS
|
||||||
|
- [Amazon Route53](https://github.com/jc21/route53-ddns)
|
||||||
|
- [Cloudflare](https://github.com/jc21/cloudflare-ddns)
|
||||||
4. Use the Nginx Proxy Manager as your gateway to forward to your other web based services
|
4. Use the Nginx Proxy Manager as your gateway to forward to your other web based services
|
||||||
|
|
||||||
## Quick Setup
|
## Quick Setup
|
||||||
|
|
||||||
1. Install Docker and Docker-Compose
|
1. [Install Docker](https://docs.docker.com/install/)
|
||||||
|
|
||||||
- [Docker Install documentation](https://docs.docker.com/install/)
|
|
||||||
- [Docker-Compose Install documentation](https://docs.docker.com/compose/install/)
|
|
||||||
|
|
||||||
2. Create a docker-compose.yml file similar to this:
|
2. Create a docker-compose.yml file similar to this:
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://biomejs.dev/schemas/2.3.2/schema.json",
|
"$schema": "https://biomejs.dev/schemas/2.4.5/schema.json",
|
||||||
"vcs": {
|
"vcs": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"clientKind": "git",
|
"clientKind": "git",
|
||||||
|
|||||||
@@ -22,6 +22,14 @@
|
|||||||
"dependencies": "",
|
"dependencies": "",
|
||||||
"credentials": "dns_aliyun_access_key = 12345678\ndns_aliyun_access_key_secret = 1234567890abcdef1234567890abcdef",
|
"credentials": "dns_aliyun_access_key = 12345678\ndns_aliyun_access_key_secret = 1234567890abcdef1234567890abcdef",
|
||||||
"full_plugin_name": "dns-aliyun"
|
"full_plugin_name": "dns-aliyun"
|
||||||
|
},
|
||||||
|
"arvan": {
|
||||||
|
"name": "ArvanCloud",
|
||||||
|
"package_name": "certbot-dns-arvan",
|
||||||
|
"version": ">=0.1.0",
|
||||||
|
"dependencies": "",
|
||||||
|
"credentials": "dns_arvan_key = Apikey xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
||||||
|
"full_plugin_name": "dns-arvan"
|
||||||
},
|
},
|
||||||
"azure": {
|
"azure": {
|
||||||
"name": "Azure",
|
"name": "Azure",
|
||||||
@@ -74,7 +82,7 @@
|
|||||||
"cloudns": {
|
"cloudns": {
|
||||||
"name": "ClouDNS",
|
"name": "ClouDNS",
|
||||||
"package_name": "certbot-dns-cloudns",
|
"package_name": "certbot-dns-cloudns",
|
||||||
"version": "~=0.6.0",
|
"version": "~=0.7.0",
|
||||||
"dependencies": "",
|
"dependencies": "",
|
||||||
"credentials": "# Target user ID (see https://www.cloudns.net/api-settings/)\n\tdns_cloudns_auth_id=1234\n\t# Alternatively, one of the following two options can be set:\n\t# dns_cloudns_sub_auth_id=1234\n\t# dns_cloudns_sub_auth_user=foobar\n\n\t# API password\n\tdns_cloudns_auth_password=password1",
|
"credentials": "# Target user ID (see https://www.cloudns.net/api-settings/)\n\tdns_cloudns_auth_id=1234\n\t# Alternatively, one of the following two options can be set:\n\t# dns_cloudns_sub_auth_id=1234\n\t# dns_cloudns_sub_auth_user=foobar\n\n\t# API password\n\tdns_cloudns_auth_password=password1",
|
||||||
"full_plugin_name": "dns-cloudns"
|
"full_plugin_name": "dns-cloudns"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"database": {
|
"database": {
|
||||||
"engine": "knex-native",
|
"engine": "knex-native",
|
||||||
"knex": {
|
"knex": {
|
||||||
"client": "sqlite3",
|
"client": "better-sqlite3",
|
||||||
"connection": {
|
"connection": {
|
||||||
"filename": "/app/config/mydb.sqlite"
|
"filename": "/app/config/mydb.sqlite"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import crypto from "node:crypto";
|
import crypto from "node:crypto";
|
||||||
import bcrypt from "bcrypt";
|
import bcrypt from "bcrypt";
|
||||||
import { authenticator } from "otplib";
|
import { createGuardrails, generateSecret, generateURI, verify } from "otplib";
|
||||||
import errs from "../lib/error.js";
|
import errs from "../lib/error.js";
|
||||||
import authModel from "../models/auth.js";
|
import authModel from "../models/auth.js";
|
||||||
import internalUser from "./user.js";
|
import internalUser from "./user.js";
|
||||||
@@ -27,7 +27,6 @@ const generateBackupCodes = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const internal2fa = {
|
const internal2fa = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if user has 2FA enabled
|
* Check if user has 2FA enabled
|
||||||
* @param {number} userId
|
* @param {number} userId
|
||||||
@@ -72,8 +71,12 @@ const internal2fa = {
|
|||||||
startSetup: async (access, userId) => {
|
startSetup: async (access, userId) => {
|
||||||
await access.can("users:password", userId);
|
await access.can("users:password", userId);
|
||||||
const user = await internalUser.get(access, { id: userId });
|
const user = await internalUser.get(access, { id: userId });
|
||||||
const secret = authenticator.generateSecret();
|
const secret = generateSecret();
|
||||||
const otpauth_url = authenticator.keyuri(user.email, APP_NAME, secret);
|
const otpauth_url = generateURI({
|
||||||
|
issuer: APP_NAME,
|
||||||
|
label: user.email,
|
||||||
|
secret: secret,
|
||||||
|
});
|
||||||
const auth = await internal2fa.getUserPasswordAuth(userId);
|
const auth = await internal2fa.getUserPasswordAuth(userId);
|
||||||
|
|
||||||
// ensure user isn't already setup for 2fa
|
// ensure user isn't already setup for 2fa
|
||||||
@@ -85,7 +88,8 @@ const internal2fa = {
|
|||||||
const meta = auth.meta || {};
|
const meta = auth.meta || {};
|
||||||
meta.totp_pending_secret = secret;
|
meta.totp_pending_secret = secret;
|
||||||
|
|
||||||
await authModel.query()
|
await authModel
|
||||||
|
.query()
|
||||||
.where("id", auth.id)
|
.where("id", auth.id)
|
||||||
.andWhere("user_id", userId)
|
.andWhere("user_id", userId)
|
||||||
.andWhere("type", "password")
|
.andWhere("type", "password")
|
||||||
@@ -112,8 +116,8 @@ const internal2fa = {
|
|||||||
throw new errs.ValidationError("No pending 2FA setup found");
|
throw new errs.ValidationError("No pending 2FA setup found");
|
||||||
}
|
}
|
||||||
|
|
||||||
const valid = authenticator.verify({ token: code, secret });
|
const result = await verify({ token: code, secret });
|
||||||
if (!valid) {
|
if (!result.valid) {
|
||||||
throw new errs.ValidationError("Invalid verification code");
|
throw new errs.ValidationError("Invalid verification code");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,12 +160,15 @@ const internal2fa = {
|
|||||||
throw new errs.ValidationError("2FA is not enabled");
|
throw new errs.ValidationError("2FA is not enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
const valid = authenticator.verify({
|
const result = await verify({
|
||||||
token: code,
|
token: code,
|
||||||
secret: auth.meta.totp_secret,
|
secret: auth.meta.totp_secret,
|
||||||
|
guardrails: createGuardrails({
|
||||||
|
MIN_SECRET_BYTES: 10,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!valid) {
|
if (!result.valid) {
|
||||||
throw new errs.AuthError("Invalid verification code");
|
throw new errs.AuthError("Invalid verification code");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,20 +201,30 @@ const internal2fa = {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try TOTP code first
|
// Try TOTP code first, if it's 6 chars. it will throw errors if it's not 6 chars
|
||||||
const valid = authenticator.verify({
|
// and the backup codes are 8 chars.
|
||||||
|
if (token.length === 6) {
|
||||||
|
const result = await verify({
|
||||||
token,
|
token,
|
||||||
secret,
|
secret,
|
||||||
|
// These guardrails lower the minimum length requirement for secrets.
|
||||||
|
// In v12 of otplib the default minimum length is 10 and in v13 it is 16.
|
||||||
|
// Since there are 2fa secrets in the wild generated with v12 we need to allow shorter secrets
|
||||||
|
// so people won't be locked out when upgrading.
|
||||||
|
guardrails: createGuardrails({
|
||||||
|
MIN_SECRET_BYTES: 10,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (valid) {
|
if (result.valid) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Try backup codes
|
// Try backup codes
|
||||||
const backupCodes = auth?.meta?.backup_codes || [];
|
const backupCodes = auth?.meta?.backup_codes || [];
|
||||||
for (let i = 0; i < backupCodes.length; i++) {
|
for (let i = 0; i < backupCodes.length; i++) {
|
||||||
const match = await bcrypt.compare(code.toUpperCase(), backupCodes[i]);
|
const match = await bcrypt.compare(token.toUpperCase(), backupCodes[i]);
|
||||||
if (match) {
|
if (match) {
|
||||||
// Remove used backup code
|
// Remove used backup code
|
||||||
const updatedCodes = [...backupCodes];
|
const updatedCodes = [...backupCodes];
|
||||||
@@ -248,12 +265,12 @@ const internal2fa = {
|
|||||||
throw new errs.ValidationError("No 2FA secret found");
|
throw new errs.ValidationError("No 2FA secret found");
|
||||||
}
|
}
|
||||||
|
|
||||||
const valid = authenticator.verify({
|
const result = await verify({
|
||||||
token,
|
token,
|
||||||
secret,
|
secret,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!valid) {
|
if (!result.valid) {
|
||||||
throw new errs.ValidationError("Invalid verification code");
|
throw new errs.ValidationError("Invalid verification code");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -630,7 +630,7 @@ const internalCertificate = {
|
|||||||
* @param {String} privateKey This is the entire key contents as a string
|
* @param {String} privateKey This is the entire key contents as a string
|
||||||
*/
|
*/
|
||||||
checkPrivateKey: async (privateKey) => {
|
checkPrivateKey: async (privateKey) => {
|
||||||
const filepath = await tempWrite(privateKey, "/tmp");
|
const filepath = await tempWrite(privateKey);
|
||||||
const failTimeout = setTimeout(() => {
|
const failTimeout = setTimeout(() => {
|
||||||
throw new error.ValidationError(
|
throw new error.ValidationError(
|
||||||
"Result Validation Error: Validation timed out. This could be due to the key being passphrase-protected.",
|
"Result Validation Error: Validation timed out. This could be due to the key being passphrase-protected.",
|
||||||
@@ -660,8 +660,8 @@ const internalCertificate = {
|
|||||||
* @param {Boolean} [throwExpired] Throw when the certificate is out of date
|
* @param {Boolean} [throwExpired] Throw when the certificate is out of date
|
||||||
*/
|
*/
|
||||||
getCertificateInfo: async (certificate, throwExpired) => {
|
getCertificateInfo: async (certificate, throwExpired) => {
|
||||||
|
const filepath = await tempWrite(certificate);
|
||||||
try {
|
try {
|
||||||
const filepath = await tempWrite(certificate, "/tmp");
|
|
||||||
const certData = await internalCertificate.getCertificateInfoFromFile(filepath, throwExpired);
|
const certData = await internalCertificate.getCertificateInfoFromFile(filepath, throwExpired);
|
||||||
fs.unlinkSync(filepath);
|
fs.unlinkSync(filepath);
|
||||||
return certData;
|
return certData;
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ const internalDeadHost = {
|
|||||||
.query()
|
.query()
|
||||||
.where("is_deleted", 0)
|
.where("is_deleted", 0)
|
||||||
.andWhere("id", data.id)
|
.andWhere("id", data.id)
|
||||||
.allowGraph("[owner,certificate]")
|
.allowGraph(deadHostModel.defaultAllowGraph)
|
||||||
.first();
|
.first();
|
||||||
|
|
||||||
if (accessData.permission_visibility !== "all") {
|
if (accessData.permission_visibility !== "all") {
|
||||||
@@ -347,7 +347,7 @@ const internalDeadHost = {
|
|||||||
.query()
|
.query()
|
||||||
.where("is_deleted", 0)
|
.where("is_deleted", 0)
|
||||||
.groupBy("id")
|
.groupBy("id")
|
||||||
.allowGraph("[owner,certificate]")
|
.allowGraph(deadHostModel.defaultAllowGraph)
|
||||||
.orderBy(castJsonIfNeed("domain_names"), "ASC");
|
.orderBy(castJsonIfNeed("domain_names"), "ASC");
|
||||||
|
|
||||||
if (accessData.permission_visibility !== "all") {
|
if (accessData.permission_visibility !== "all") {
|
||||||
|
|||||||
@@ -115,9 +115,9 @@ const internalProxyHost = {
|
|||||||
*/
|
*/
|
||||||
update: (access, data) => {
|
update: (access, data) => {
|
||||||
let thisData = data;
|
let thisData = data;
|
||||||
const create_certificate = thisData.certificate_id === "new";
|
const createCertificate = thisData.certificate_id === "new";
|
||||||
|
|
||||||
if (create_certificate) {
|
if (createCertificate) {
|
||||||
delete thisData.certificate_id;
|
delete thisData.certificate_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ const internalProxyHost = {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (create_certificate) {
|
if (createCertificate) {
|
||||||
return internalCertificate
|
return internalCertificate
|
||||||
.createQuickCertificate(access, {
|
.createQuickCertificate(access, {
|
||||||
domain_names: thisData.domain_names || row.domain_names,
|
domain_names: thisData.domain_names || row.domain_names,
|
||||||
@@ -232,7 +232,6 @@ const internalProxyHost = {
|
|||||||
*/
|
*/
|
||||||
get: (access, data) => {
|
get: (access, data) => {
|
||||||
const thisData = data || {};
|
const thisData = data || {};
|
||||||
|
|
||||||
return access
|
return access
|
||||||
.can("proxy_hosts:get", thisData.id)
|
.can("proxy_hosts:get", thisData.id)
|
||||||
.then((access_data) => {
|
.then((access_data) => {
|
||||||
@@ -240,7 +239,7 @@ const internalProxyHost = {
|
|||||||
.query()
|
.query()
|
||||||
.where("is_deleted", 0)
|
.where("is_deleted", 0)
|
||||||
.andWhere("id", thisData.id)
|
.andWhere("id", thisData.id)
|
||||||
.allowGraph("[owner,access_list.[clients,items],certificate]")
|
.allowGraph(proxyHostModel.defaultAllowGraph)
|
||||||
.first();
|
.first();
|
||||||
|
|
||||||
if (access_data.permission_visibility !== "all") {
|
if (access_data.permission_visibility !== "all") {
|
||||||
@@ -422,11 +421,12 @@ const internalProxyHost = {
|
|||||||
*/
|
*/
|
||||||
getAll: async (access, expand, searchQuery) => {
|
getAll: async (access, expand, searchQuery) => {
|
||||||
const accessData = await access.can("proxy_hosts:list");
|
const accessData = await access.can("proxy_hosts:list");
|
||||||
|
|
||||||
const query = proxyHostModel
|
const query = proxyHostModel
|
||||||
.query()
|
.query()
|
||||||
.where("is_deleted", 0)
|
.where("is_deleted", 0)
|
||||||
.groupBy("id")
|
.groupBy("id")
|
||||||
.allowGraph("[owner,access_list,certificate]")
|
.allowGraph(proxyHostModel.defaultAllowGraph)
|
||||||
.orderBy(castJsonIfNeed("domain_names"), "ASC");
|
.orderBy(castJsonIfNeed("domain_names"), "ASC");
|
||||||
|
|
||||||
if (accessData.permission_visibility !== "all") {
|
if (accessData.permission_visibility !== "all") {
|
||||||
|
|||||||
@@ -229,7 +229,6 @@ const internalRedirectionHost = {
|
|||||||
*/
|
*/
|
||||||
get: (access, data) => {
|
get: (access, data) => {
|
||||||
const thisData = data || {};
|
const thisData = data || {};
|
||||||
|
|
||||||
return access
|
return access
|
||||||
.can("redirection_hosts:get", thisData.id)
|
.can("redirection_hosts:get", thisData.id)
|
||||||
.then((access_data) => {
|
.then((access_data) => {
|
||||||
@@ -237,7 +236,7 @@ const internalRedirectionHost = {
|
|||||||
.query()
|
.query()
|
||||||
.where("is_deleted", 0)
|
.where("is_deleted", 0)
|
||||||
.andWhere("id", thisData.id)
|
.andWhere("id", thisData.id)
|
||||||
.allowGraph("[owner,certificate]")
|
.allowGraph(redirectionHostModel.defaultAllowGraph)
|
||||||
.first();
|
.first();
|
||||||
|
|
||||||
if (access_data.permission_visibility !== "all") {
|
if (access_data.permission_visibility !== "all") {
|
||||||
@@ -426,7 +425,7 @@ const internalRedirectionHost = {
|
|||||||
.query()
|
.query()
|
||||||
.where("is_deleted", 0)
|
.where("is_deleted", 0)
|
||||||
.groupBy("id")
|
.groupBy("id")
|
||||||
.allowGraph("[owner,certificate]")
|
.allowGraph(redirectionHostModel.defaultAllowGraph)
|
||||||
.orderBy(castJsonIfNeed("domain_names"), "ASC");
|
.orderBy(castJsonIfNeed("domain_names"), "ASC");
|
||||||
|
|
||||||
if (access_data.permission_visibility !== "all") {
|
if (access_data.permission_visibility !== "all") {
|
||||||
|
|||||||
@@ -178,7 +178,6 @@ const internalStream = {
|
|||||||
*/
|
*/
|
||||||
get: (access, data) => {
|
get: (access, data) => {
|
||||||
const thisData = data || {};
|
const thisData = data || {};
|
||||||
|
|
||||||
return access
|
return access
|
||||||
.can("streams:get", thisData.id)
|
.can("streams:get", thisData.id)
|
||||||
.then((access_data) => {
|
.then((access_data) => {
|
||||||
@@ -186,7 +185,7 @@ const internalStream = {
|
|||||||
.query()
|
.query()
|
||||||
.where("is_deleted", 0)
|
.where("is_deleted", 0)
|
||||||
.andWhere("id", thisData.id)
|
.andWhere("id", thisData.id)
|
||||||
.allowGraph("[owner,certificate]")
|
.allowGraph(streamModel.defaultAllowGraph)
|
||||||
.first();
|
.first();
|
||||||
|
|
||||||
if (access_data.permission_visibility !== "all") {
|
if (access_data.permission_visibility !== "all") {
|
||||||
@@ -375,7 +374,7 @@ const internalStream = {
|
|||||||
.query()
|
.query()
|
||||||
.where("is_deleted", 0)
|
.where("is_deleted", 0)
|
||||||
.groupBy("id")
|
.groupBy("id")
|
||||||
.allowGraph("[owner,certificate]")
|
.allowGraph(streamModel.defaultAllowGraph)
|
||||||
.orderBy("incoming_port", "ASC");
|
.orderBy("incoming_port", "ASC");
|
||||||
|
|
||||||
if (access_data.permission_visibility !== "all") {
|
if (access_data.permission_visibility !== "all") {
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ import { global as logger } from "../logger.js";
|
|||||||
const keysFile = '/data/keys.json';
|
const keysFile = '/data/keys.json';
|
||||||
const mysqlEngine = 'mysql2';
|
const mysqlEngine = 'mysql2';
|
||||||
const postgresEngine = 'pg';
|
const postgresEngine = 'pg';
|
||||||
const sqliteClientName = 'sqlite3';
|
const sqliteClientName = 'better-sqlite3';
|
||||||
|
|
||||||
|
// Not used for new setups anymore but may exist in legacy setups
|
||||||
|
const legacySqliteClientName = 'sqlite3';
|
||||||
|
|
||||||
let instance = null;
|
let instance = null;
|
||||||
|
|
||||||
@@ -84,6 +87,7 @@ const configure = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const envSqliteFile = process.env.DB_SQLITE_FILE || "/data/database.sqlite";
|
const envSqliteFile = process.env.DB_SQLITE_FILE || "/data/database.sqlite";
|
||||||
|
|
||||||
logger.info(`Using Sqlite: ${envSqliteFile}`);
|
logger.info(`Using Sqlite: ${envSqliteFile}`);
|
||||||
instance = {
|
instance = {
|
||||||
database: {
|
database: {
|
||||||
@@ -183,7 +187,7 @@ const configGet = (key) => {
|
|||||||
*/
|
*/
|
||||||
const isSqlite = () => {
|
const isSqlite = () => {
|
||||||
instance === null && configure();
|
instance === null && configure();
|
||||||
return instance.database.knex && instance.database.knex.client === sqliteClientName;
|
return instance.database.knex && [sqliteClientName, legacySqliteClientName].includes(instance.database.knex.client);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
43
backend/migrations/20260131163528_trust_forwarded_proto.js
Normal file
43
backend/migrations/20260131163528_trust_forwarded_proto.js
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { migrate as logger } from "../logger.js";
|
||||||
|
|
||||||
|
const migrateName = "trust_forwarded_proto";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate
|
||||||
|
*
|
||||||
|
* @see http://knexjs.org/#Schema
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
const up = function (knex) {
|
||||||
|
logger.info(`[${migrateName}] Migrating Up...`);
|
||||||
|
|
||||||
|
return knex.schema
|
||||||
|
.alterTable('proxy_host', (table) => {
|
||||||
|
table.tinyint('trust_forwarded_proto').notNullable().defaultTo(0);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
logger.info(`[${migrateName}] proxy_host Table altered`);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo Migrate
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
const down = function (knex) {
|
||||||
|
logger.info(`[${migrateName}] Migrating Down...`);
|
||||||
|
|
||||||
|
return knex.schema
|
||||||
|
.alterTable('proxy_host', (table) => {
|
||||||
|
table.dropColumn('trust_forwarded_proto');
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
logger.info(`[${migrateName}] proxy_host Table altered`);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export { up, down };
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import { Model } from "objection";
|
import { Model } from "objection";
|
||||||
import db from "../db.js";
|
import db from "../db.js";
|
||||||
import { convertBoolFieldsToInt, convertIntFieldsToBool } from "../lib/helpers.js";
|
import { castJsonIfNeed, convertBoolFieldsToInt, convertIntFieldsToBool } from "../lib/helpers.js";
|
||||||
import Certificate from "./certificate.js";
|
import Certificate from "./certificate.js";
|
||||||
import now from "./now_helper.js";
|
import now from "./now_helper.js";
|
||||||
import User from "./user.js";
|
import User from "./user.js";
|
||||||
@@ -61,6 +61,18 @@ class DeadHost extends Model {
|
|||||||
return ["domain_names", "meta"];
|
return ["domain_names", "meta"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get defaultAllowGraph() {
|
||||||
|
return "[owner,certificate]";
|
||||||
|
}
|
||||||
|
|
||||||
|
static get defaultExpand() {
|
||||||
|
return ["certificate", "owner"];
|
||||||
|
}
|
||||||
|
|
||||||
|
static get defaultOrder() {
|
||||||
|
return [castJsonIfNeed("domain_names"), "ASC"];
|
||||||
|
}
|
||||||
|
|
||||||
static get relationMappings() {
|
static get relationMappings() {
|
||||||
return {
|
return {
|
||||||
owner: {
|
owner: {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import { Model } from "objection";
|
import { Model } from "objection";
|
||||||
import db from "../db.js";
|
import db from "../db.js";
|
||||||
import { convertBoolFieldsToInt, convertIntFieldsToBool } from "../lib/helpers.js";
|
import { castJsonIfNeed, convertBoolFieldsToInt, convertIntFieldsToBool } from "../lib/helpers.js";
|
||||||
import AccessList from "./access_list.js";
|
import AccessList from "./access_list.js";
|
||||||
import Certificate from "./certificate.js";
|
import Certificate from "./certificate.js";
|
||||||
import now from "./now_helper.js";
|
import now from "./now_helper.js";
|
||||||
@@ -21,6 +21,7 @@ const boolFields = [
|
|||||||
"enabled",
|
"enabled",
|
||||||
"hsts_enabled",
|
"hsts_enabled",
|
||||||
"hsts_subdomains",
|
"hsts_subdomains",
|
||||||
|
"trust_forwarded_proto",
|
||||||
];
|
];
|
||||||
|
|
||||||
class ProxyHost extends Model {
|
class ProxyHost extends Model {
|
||||||
@@ -72,6 +73,18 @@ class ProxyHost extends Model {
|
|||||||
return ["domain_names", "meta", "locations"];
|
return ["domain_names", "meta", "locations"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get defaultAllowGraph() {
|
||||||
|
return "[owner,access_list.[clients,items],certificate]";
|
||||||
|
}
|
||||||
|
|
||||||
|
static get defaultExpand() {
|
||||||
|
return ["owner", "certificate", "access_list.[clients,items]"];
|
||||||
|
}
|
||||||
|
|
||||||
|
static get defaultOrder() {
|
||||||
|
return [castJsonIfNeed("domain_names"), "ASC"];
|
||||||
|
}
|
||||||
|
|
||||||
static get relationMappings() {
|
static get relationMappings() {
|
||||||
return {
|
return {
|
||||||
owner: {
|
owner: {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import { Model } from "objection";
|
import { Model } from "objection";
|
||||||
import db from "../db.js";
|
import db from "../db.js";
|
||||||
import { convertBoolFieldsToInt, convertIntFieldsToBool } from "../lib/helpers.js";
|
import { castJsonIfNeed, convertBoolFieldsToInt, convertIntFieldsToBool } from "../lib/helpers.js";
|
||||||
import Certificate from "./certificate.js";
|
import Certificate from "./certificate.js";
|
||||||
import now from "./now_helper.js";
|
import now from "./now_helper.js";
|
||||||
import User from "./user.js";
|
import User from "./user.js";
|
||||||
@@ -70,6 +70,18 @@ class RedirectionHost extends Model {
|
|||||||
return ["domain_names", "meta"];
|
return ["domain_names", "meta"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get defaultAllowGraph() {
|
||||||
|
return "[owner,certificate]";
|
||||||
|
}
|
||||||
|
|
||||||
|
static get defaultExpand() {
|
||||||
|
return ["certificate", "owner"];
|
||||||
|
}
|
||||||
|
|
||||||
|
static get defaultOrder() {
|
||||||
|
return [castJsonIfNeed("domain_names"), "ASC"];
|
||||||
|
}
|
||||||
|
|
||||||
static get relationMappings() {
|
static get relationMappings() {
|
||||||
return {
|
return {
|
||||||
owner: {
|
owner: {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Model } from "objection";
|
import { Model } from "objection";
|
||||||
import db from "../db.js";
|
import db from "../db.js";
|
||||||
import { convertBoolFieldsToInt, convertIntFieldsToBool } from "../lib/helpers.js";
|
import { castJsonIfNeed, convertBoolFieldsToInt, convertIntFieldsToBool } from "../lib/helpers.js";
|
||||||
import Certificate from "./certificate.js";
|
import Certificate from "./certificate.js";
|
||||||
import now from "./now_helper.js";
|
import now from "./now_helper.js";
|
||||||
import User from "./user.js";
|
import User from "./user.js";
|
||||||
@@ -46,6 +46,18 @@ class Stream extends Model {
|
|||||||
return ["meta"];
|
return ["meta"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get defaultAllowGraph() {
|
||||||
|
return "[owner,certificate]";
|
||||||
|
}
|
||||||
|
|
||||||
|
static get defaultExpand() {
|
||||||
|
return ["certificate", "owner"];
|
||||||
|
}
|
||||||
|
|
||||||
|
static get defaultOrder() {
|
||||||
|
return [castJsonIfNeed("incoming_port"), "ASC"];
|
||||||
|
}
|
||||||
|
|
||||||
static get relationMappings() {
|
static get relationMappings() {
|
||||||
return {
|
return {
|
||||||
owner: {
|
owner: {
|
||||||
|
|||||||
@@ -9,40 +9,42 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "biome lint",
|
"lint": "biome lint",
|
||||||
"prettier": "biome format --write .",
|
"prettier": "biome format --write .",
|
||||||
"validate-schema": "node validate-schema.js"
|
"validate-schema": "node validate-schema.js",
|
||||||
|
"regenerate-config": "node scripts/regenerate-config"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apidevtools/json-schema-ref-parser": "^11.7.0",
|
"@apidevtools/json-schema-ref-parser": "^15.3.1",
|
||||||
"ajv": "^8.17.1",
|
"ajv": "^8.18.0",
|
||||||
"archiver": "^5.3.0",
|
"archiver": "^7.0.1",
|
||||||
"batchflow": "^0.4.0",
|
"batchflow": "^0.4.0",
|
||||||
"bcrypt": "^5.0.0",
|
"bcrypt": "^6.0.0",
|
||||||
"body-parser": "^1.20.3",
|
"better-sqlite3": "^12.6.2",
|
||||||
"compression": "^1.7.4",
|
"body-parser": "^2.2.2",
|
||||||
"express": "^4.22.0",
|
"compression": "^1.8.1",
|
||||||
|
"express": "^5.2.1",
|
||||||
"express-fileupload": "^1.5.2",
|
"express-fileupload": "^1.5.2",
|
||||||
"gravatar": "^1.8.2",
|
"gravatar": "^1.8.2",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.3",
|
||||||
"knex": "2.4.2",
|
"knex": "3.1.0",
|
||||||
"liquidjs": "10.6.1",
|
"liquidjs": "10.24.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.23",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"mysql2": "^3.15.3",
|
"mysql2": "^3.18.2",
|
||||||
"node-rsa": "^1.1.1",
|
"node-rsa": "^1.1.1",
|
||||||
"objection": "3.0.1",
|
"objection": "3.1.5",
|
||||||
"otplib": "^12.0.1",
|
"otplib": "^13.3.0",
|
||||||
"path": "^0.12.7",
|
"path": "^0.12.7",
|
||||||
"pg": "^8.16.3",
|
"pg": "^8.19.0",
|
||||||
"proxy-agent": "^6.5.0",
|
"proxy-agent": "^6.5.0",
|
||||||
"signale": "1.4.0",
|
"signale": "1.4.0",
|
||||||
"sqlite3": "^5.1.7",
|
"sqlite3": "^5.1.7",
|
||||||
"temp-write": "^4.0.0"
|
"temp-write": "^6.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@apidevtools/swagger-parser": "^10.1.0",
|
"@apidevtools/swagger-parser": "^12.1.0",
|
||||||
"@biomejs/biome": "^2.3.2",
|
"@biomejs/biome": "^2.4.5",
|
||||||
"chalk": "4.1.2",
|
"chalk": "5.6.2",
|
||||||
"nodemon": "^2.0.2"
|
"nodemon": "^3.1.14"
|
||||||
},
|
},
|
||||||
"signale": {
|
"signale": {
|
||||||
"displayDate": true,
|
"displayDate": true,
|
||||||
|
|||||||
@@ -22,7 +22,8 @@
|
|||||||
"enabled",
|
"enabled",
|
||||||
"locations",
|
"locations",
|
||||||
"hsts_enabled",
|
"hsts_enabled",
|
||||||
"hsts_subdomains"
|
"hsts_subdomains",
|
||||||
|
"trust_forwarded_proto"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
@@ -141,6 +142,11 @@
|
|||||||
"hsts_subdomains": {
|
"hsts_subdomains": {
|
||||||
"$ref": "../common.json#/properties/hsts_subdomains"
|
"$ref": "../common.json#/properties/hsts_subdomains"
|
||||||
},
|
},
|
||||||
|
"trust_forwarded_proto":{
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Trust the forwarded headers",
|
||||||
|
"example": false
|
||||||
|
},
|
||||||
"certificate": {
|
"certificate": {
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -58,7 +58,8 @@
|
|||||||
"enabled": true,
|
"enabled": true,
|
||||||
"locations": [],
|
"locations": [],
|
||||||
"hsts_enabled": false,
|
"hsts_enabled": false,
|
||||||
"hsts_subdomains": false
|
"hsts_subdomains": false,
|
||||||
|
"trust_forwarded_proto": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
"locations": [],
|
"locations": [],
|
||||||
"hsts_enabled": false,
|
"hsts_enabled": false,
|
||||||
"hsts_subdomains": false,
|
"hsts_subdomains": false,
|
||||||
|
"trust_forwarded_proto": false,
|
||||||
"owner": {
|
"owner": {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"created_on": "2025-10-28T00:50:24.000Z",
|
"created_on": "2025-10-28T00:50:24.000Z",
|
||||||
|
|||||||
@@ -56,6 +56,9 @@
|
|||||||
"hsts_subdomains": {
|
"hsts_subdomains": {
|
||||||
"$ref": "../../../../components/proxy-host-object.json#/properties/hsts_subdomains"
|
"$ref": "../../../../components/proxy-host-object.json#/properties/hsts_subdomains"
|
||||||
},
|
},
|
||||||
|
"trust_forwarded_proto": {
|
||||||
|
"$ref": "../../../../components/proxy-host-object.json#/properties/trust_forwarded_proto"
|
||||||
|
},
|
||||||
"http2_support": {
|
"http2_support": {
|
||||||
"$ref": "../../../../components/proxy-host-object.json#/properties/http2_support"
|
"$ref": "../../../../components/proxy-host-object.json#/properties/http2_support"
|
||||||
},
|
},
|
||||||
@@ -122,6 +125,7 @@
|
|||||||
"locations": [],
|
"locations": [],
|
||||||
"hsts_enabled": false,
|
"hsts_enabled": false,
|
||||||
"hsts_subdomains": false,
|
"hsts_subdomains": false,
|
||||||
|
"trust_forwarded_proto": false,
|
||||||
"owner": {
|
"owner": {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"created_on": "2025-10-28T00:50:24.000Z",
|
"created_on": "2025-10-28T00:50:24.000Z",
|
||||||
|
|||||||
@@ -48,6 +48,9 @@
|
|||||||
"hsts_subdomains": {
|
"hsts_subdomains": {
|
||||||
"$ref": "../../../components/proxy-host-object.json#/properties/hsts_subdomains"
|
"$ref": "../../../components/proxy-host-object.json#/properties/hsts_subdomains"
|
||||||
},
|
},
|
||||||
|
"trust_forwarded_proto": {
|
||||||
|
"$ref": "../../../components/proxy-host-object.json#/properties/trust_forwarded_proto"
|
||||||
|
},
|
||||||
"http2_support": {
|
"http2_support": {
|
||||||
"$ref": "../../../components/proxy-host-object.json#/properties/http2_support"
|
"$ref": "../../../components/proxy-host-object.json#/properties/http2_support"
|
||||||
},
|
},
|
||||||
@@ -119,6 +122,7 @@
|
|||||||
"locations": [],
|
"locations": [],
|
||||||
"hsts_enabled": false,
|
"hsts_enabled": false,
|
||||||
"hsts_subdomains": false,
|
"hsts_subdomains": false,
|
||||||
|
"trust_forwarded_proto": false,
|
||||||
"certificate": null,
|
"certificate": null,
|
||||||
"owner": {
|
"owner": {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
},
|
},
|
||||||
"code": {
|
"code": {
|
||||||
"minLength": 6,
|
"minLength": 6,
|
||||||
"maxLength": 6,
|
"maxLength": 8,
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"example": "012345"
|
"example": "012345"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"description": "Verififcation Payload",
|
"description": "Verification Payload",
|
||||||
"required": true,
|
"required": true,
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"code": {
|
"code": {
|
||||||
"minLength": 6,
|
"minLength": 6,
|
||||||
"maxLength": 6,
|
"maxLength": 8,
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"example": "123456"
|
"example": "123456"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"description": "Verififcation Payload",
|
"description": "Verification Payload",
|
||||||
"required": true,
|
"required": true,
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"code": {
|
"code": {
|
||||||
"minLength": 6,
|
"minLength": 6,
|
||||||
"maxLength": 6,
|
"maxLength": 8,
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"example": "123456"
|
"example": "123456"
|
||||||
}
|
}
|
||||||
|
|||||||
76
backend/scripts/regenerate-config
Executable file
76
backend/scripts/regenerate-config
Executable file
@@ -0,0 +1,76 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import * as process from "node:process"; // Use the node: protocol for built-ins
|
||||||
|
import internalNginx from "../internal/nginx.js";
|
||||||
|
import { global as logger } from "../logger.js";
|
||||||
|
import deadHostModel from "../models/dead_host.js";
|
||||||
|
import proxyHostModel from "../models/proxy_host.js";
|
||||||
|
import redirectionHostModel from "../models/redirection_host.js";
|
||||||
|
import streamModel from "../models/stream.js";
|
||||||
|
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
const UNATTENDED = args.includes("-y") || args.includes("--yes");
|
||||||
|
const DRY_RUN = args.includes("--dry-run");
|
||||||
|
|
||||||
|
if (args.includes("--help") || args.includes("-h")) {
|
||||||
|
console.log("\nThis will iterate over all Hosts and regnerate their Nginx configs.\n")
|
||||||
|
console.log("Usage: ./regenerate-config [-h|--help] [-y|--yes] [--dry-run]\n");
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ask for the user to confirm the action if not in unattended mode
|
||||||
|
if (!UNATTENDED && !DRY_RUN) {
|
||||||
|
const readline = await import("node:readline");
|
||||||
|
const rl = readline.createInterface({
|
||||||
|
input: process.stdin,
|
||||||
|
output: process.stdout,
|
||||||
|
});
|
||||||
|
|
||||||
|
const question = (query) =>
|
||||||
|
new Promise((resolve) => rl.question(query, resolve));
|
||||||
|
|
||||||
|
const answer = await question(
|
||||||
|
"This will iterate over all Hosts and regnerate their Nginx configs.\n\nAre you sure you want to proceed? (y/N) ",
|
||||||
|
);
|
||||||
|
rl.close();
|
||||||
|
|
||||||
|
if (answer.toLowerCase() !== "y") {
|
||||||
|
console.log("Aborting.");
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const logIt = (msg, type = "info") => logger[type](
|
||||||
|
`${DRY_RUN ? '[DRY RUN] ' : ''}${msg}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Let's do it.
|
||||||
|
|
||||||
|
const processItems = async (model, type) => {
|
||||||
|
const rows = await model
|
||||||
|
.query()
|
||||||
|
.where("is_deleted", 0)
|
||||||
|
.andWhere("enabled", 1)
|
||||||
|
.groupBy("id")
|
||||||
|
.allowGraph(model.defaultAllowGraph)
|
||||||
|
.withGraphFetched(`[${model.defaultExpand.join(", ")}]`)
|
||||||
|
.orderBy(...model.defaultOrder);
|
||||||
|
|
||||||
|
logIt(`[${type}] Found ${rows.length} rows to process...`);
|
||||||
|
for (const row of rows) {
|
||||||
|
if (!DRY_RUN) {
|
||||||
|
logIt(`[${type}] Regenerating config #${row.id}: ${row.domain_names ? row.domain_names.join(", ") : 'port ' + row.incoming_port}`);
|
||||||
|
await internalNginx.configure(proxyHostModel, "proxy_host", row);
|
||||||
|
} else {
|
||||||
|
logIt(`[${type}] Skipping generation of config #${row.id}: ${row.domain_names ? row.domain_names.join(", ") : 'port ' + row.incoming_port}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
await processItems(proxyHostModel, "Proxy Host");
|
||||||
|
await processItems(redirectionHostModel, "Redirection Host");
|
||||||
|
await processItems(deadHostModel, "404 Host");
|
||||||
|
await processItems(streamModel, "Stream");
|
||||||
|
|
||||||
|
logIt("Completed", "success");
|
||||||
|
process.exit(0);
|
||||||
@@ -1,6 +1,11 @@
|
|||||||
{% if certificate and certificate_id > 0 -%}
|
{% if certificate and certificate_id > 0 -%}
|
||||||
{% if ssl_forced == 1 or ssl_forced == true %}
|
{% if ssl_forced == 1 or ssl_forced == true %}
|
||||||
# Force SSL
|
# Force SSL
|
||||||
|
{% if trust_forwarded_proto == true %}
|
||||||
|
set $trust_forwarded_proto "T";
|
||||||
|
{% else %}
|
||||||
|
set $trust_forwarded_proto "F";
|
||||||
|
{% endif %}
|
||||||
include conf.d/include/force-ssl.conf;
|
include conf.d/include/force-ssl.conf;
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
1504
backend/yarn.lock
1504
backend/yarn.lock
File diff suppressed because it is too large
Load Diff
@@ -109,7 +109,7 @@ services:
|
|||||||
- "cypress_logs:/test/results"
|
- "cypress_logs:/test/results"
|
||||||
- "./dev/resolv.conf:/etc/resolv.conf:ro"
|
- "./dev/resolv.conf:/etc/resolv.conf:ro"
|
||||||
- "/etc/localtime:/etc/localtime:ro"
|
- "/etc/localtime:/etc/localtime:ro"
|
||||||
command: cypress run --browser chrome --config-file=cypress/config/ci.js
|
command: cypress run --browser chrome --config-file=cypress/config/ci.mjs
|
||||||
networks:
|
networks:
|
||||||
- fulltest
|
- fulltest
|
||||||
|
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ services:
|
|||||||
- "../test/results:/results"
|
- "../test/results:/results"
|
||||||
- "./dev/resolv.conf:/etc/resolv.conf:ro"
|
- "./dev/resolv.conf:/etc/resolv.conf:ro"
|
||||||
- "/etc/localtime:/etc/localtime:ro"
|
- "/etc/localtime:/etc/localtime:ro"
|
||||||
command: cypress run --browser chrome --config-file=cypress/config/ci.js
|
command: cypress run --browser chrome --config-file=cypress/config/ci.mjs
|
||||||
networks:
|
networks:
|
||||||
- nginx_proxy_manager
|
- nginx_proxy_manager
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,28 @@ if ($scheme = "http") {
|
|||||||
if ($request_uri = /.well-known/acme-challenge/test-challenge) {
|
if ($request_uri = /.well-known/acme-challenge/test-challenge) {
|
||||||
set $test "${test}T";
|
set $test "${test}T";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check if the ssl staff has been handled
|
||||||
|
set $test_ssl_handled "";
|
||||||
|
if ($trust_forwarded_proto = "") {
|
||||||
|
set $trust_forwarded_proto "F";
|
||||||
|
}
|
||||||
|
if ($trust_forwarded_proto = "T") {
|
||||||
|
set $test_ssl_handled "${test_ssl_handled}T";
|
||||||
|
}
|
||||||
|
if ($http_x_forwarded_proto = "https") {
|
||||||
|
set $test_ssl_handled "${test_ssl_handled}S";
|
||||||
|
}
|
||||||
|
if ($http_x_forwarded_scheme = "https") {
|
||||||
|
set $test_ssl_handled "${test_ssl_handled}S";
|
||||||
|
}
|
||||||
|
if ($test_ssl_handled = "TSS") {
|
||||||
|
set $test_ssl_handled "TS";
|
||||||
|
}
|
||||||
|
if ($test_ssl_handled = "TS") {
|
||||||
|
set $test "${test}S";
|
||||||
|
}
|
||||||
|
|
||||||
if ($test = H) {
|
if ($test = H) {
|
||||||
return 301 https://$host$request_uri;
|
return 301 https://$host$request_uri;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
add_header X-Served-By $host;
|
add_header X-Served-By $host;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Forwarded-Scheme $scheme;
|
proxy_set_header X-Forwarded-Scheme $x_forwarded_scheme;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $x_forwarded_proto;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_pass $forward_scheme://$server:$port$request_uri;
|
proxy_pass $forward_scheme://$server:$port$request_uri;
|
||||||
|
|||||||
@@ -47,16 +47,28 @@ http {
|
|||||||
proxy_cache_path /var/lib/nginx/cache/private levels=1:2 keys_zone=private-cache:5m max_size=1024m;
|
proxy_cache_path /var/lib/nginx/cache/private levels=1:2 keys_zone=private-cache:5m max_size=1024m;
|
||||||
|
|
||||||
# Log format and fallback log file
|
# Log format and fallback log file
|
||||||
include /etc/nginx/conf.d/include/log-proxy.conf;
|
include /etc/nginx/conf.d/include/log-proxy[.]conf;
|
||||||
|
|
||||||
# Dynamically generated resolvers file
|
# Dynamically generated resolvers file
|
||||||
include /etc/nginx/conf.d/include/resolvers.conf;
|
include /etc/nginx/conf.d/include/resolvers[.]conf;
|
||||||
|
|
||||||
# Default upstream scheme
|
# Default upstream scheme
|
||||||
map $host $forward_scheme {
|
map $host $forward_scheme {
|
||||||
default http;
|
default http;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Handle upstream X-Forwarded-Proto and X-Forwarded-Scheme header
|
||||||
|
map $http_x_forwarded_proto $x_forwarded_proto {
|
||||||
|
"http" "http";
|
||||||
|
"https" "https";
|
||||||
|
default $scheme;
|
||||||
|
}
|
||||||
|
map $http_x_forwarded_scheme $x_forwarded_scheme {
|
||||||
|
"http" "http";
|
||||||
|
"https" "https";
|
||||||
|
default $scheme;
|
||||||
|
}
|
||||||
|
|
||||||
# Real IP Determination
|
# Real IP Determination
|
||||||
|
|
||||||
# Local subnets:
|
# Local subnets:
|
||||||
@@ -64,7 +76,7 @@ http {
|
|||||||
set_real_ip_from 172.16.0.0/12; # Includes Docker subnet
|
set_real_ip_from 172.16.0.0/12; # Includes Docker subnet
|
||||||
set_real_ip_from 192.168.0.0/16;
|
set_real_ip_from 192.168.0.0/16;
|
||||||
# NPM generated CDN ip ranges:
|
# NPM generated CDN ip ranges:
|
||||||
include conf.d/include/ip_ranges.conf;
|
include conf.d/include/ip_ranges[.]conf;
|
||||||
# always put the following 2 lines after ip subnets:
|
# always put the following 2 lines after ip subnets:
|
||||||
real_ip_header X-Real-IP;
|
real_ip_header X-Real-IP;
|
||||||
real_ip_recursive on;
|
real_ip_recursive on;
|
||||||
@@ -86,7 +98,7 @@ http {
|
|||||||
|
|
||||||
stream {
|
stream {
|
||||||
# Log format and fallback log file
|
# Log format and fallback log file
|
||||||
include /etc/nginx/conf.d/include/log-stream.conf;
|
include /etc/nginx/conf.d/include/log-stream[.]conf;
|
||||||
|
|
||||||
# Files generated by NPM
|
# Files generated by NPM
|
||||||
include /data/nginx/stream/*.conf;
|
include /data/nginx/stream/*.conf;
|
||||||
|
|||||||
@@ -7,8 +7,10 @@ log_info 'Dynamic resolvers ...'
|
|||||||
|
|
||||||
# Dynamically generate resolvers file, if resolver is IPv6, enclose in `[]`
|
# Dynamically generate resolvers file, if resolver is IPv6, enclose in `[]`
|
||||||
# thanks @tfmm
|
# thanks @tfmm
|
||||||
if [ "$(is_true "$DISABLE_IPV6")" = '1' ]; then
|
if [ "$(is_true "${DISABLE_RESOLVER:-}")" = '0' ]; then
|
||||||
|
if [ "$(is_true "${DISABLE_IPV6:-}")" = '1' ]; then
|
||||||
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf) ipv6=off valid=10s;" > /etc/nginx/conf.d/include/resolvers.conf
|
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf) ipv6=off valid=10s;" > /etc/nginx/conf.d/include/resolvers.conf
|
||||||
else
|
else
|
||||||
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf) valid=10s;" > /etc/nginx/conf.d/include/resolvers.conf
|
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf) valid=10s;" > /etc/nginx/conf.d/include/resolvers.conf
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ process_folder () {
|
|||||||
FILES=$(find "$1" -type f -name "*.conf")
|
FILES=$(find "$1" -type f -name "*.conf")
|
||||||
SED_REGEX=
|
SED_REGEX=
|
||||||
|
|
||||||
if [ "$(is_true "$DISABLE_IPV6")" = '1' ]; then
|
if [ "$(is_true "${DISABLE_IPV6:-}")" = '1' ]; then
|
||||||
# IPV6 is disabled
|
# IPV6 is disabled
|
||||||
echo "Disabling IPV6 in hosts in: $1"
|
echo "Disabling IPV6 in hosts in: $1"
|
||||||
SED_REGEX='s/^([^#]*)listen \[::\]/\1#listen [::]/g'
|
SED_REGEX='s/^([^#]*)listen \[::\]/\1#listen [::]/g'
|
||||||
@@ -25,7 +25,13 @@ process_folder () {
|
|||||||
for FILE in $FILES
|
for FILE in $FILES
|
||||||
do
|
do
|
||||||
echo "- ${FILE}"
|
echo "- ${FILE}"
|
||||||
echo "$(sed -E "$SED_REGEX" "$FILE")" > $FILE
|
TMPFILE="${FILE}.tmp"
|
||||||
|
if sed -E "$SED_REGEX" "$FILE" > "$TMPFILE" && [ -s "$TMPFILE" ]; then
|
||||||
|
mv "$TMPFILE" "$FILE"
|
||||||
|
else
|
||||||
|
echo "WARNING: skipping ${FILE} — sed produced empty output" >&2
|
||||||
|
rm -f "$TMPFILE"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# ensure the files are still owned by the npm user
|
# ensure the files are still owned by the npm user
|
||||||
|
|||||||
@@ -17,10 +17,6 @@ case $TARGETPLATFORM in
|
|||||||
S6_ARCH=aarch64
|
S6_ARCH=aarch64
|
||||||
;;
|
;;
|
||||||
|
|
||||||
linux/arm/v7)
|
|
||||||
S6_ARCH=armhf
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
*)
|
||||||
S6_ARCH=x86_64
|
S6_ARCH=x86_64
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vitepress dev --host",
|
"dev": "vitepress dev --host",
|
||||||
"build": "vitepress build",
|
"build": "vitepress build",
|
||||||
"preview": "vitepress preview"
|
"preview": "vitepress preview",
|
||||||
|
"set-version": "./scripts/set-version.sh"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"vitepress": "^1.6.4"
|
"vitepress": "^1.6.4"
|
||||||
|
|||||||
17
docs/scripts/set-version.sh
Executable file
17
docs/scripts/set-version.sh
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euf
|
||||||
|
|
||||||
|
# this script accepts a version number as an argument
|
||||||
|
# and replaces {{VERSION}} in src/*.md with the provided version number.
|
||||||
|
|
||||||
|
if [ "$#" -ne 1 ]; then
|
||||||
|
echo "Usage: $0 <version>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
cd "$DIR/.." || exit 1
|
||||||
|
|
||||||
|
VERSION="$1"
|
||||||
|
# find all .md files in src/ and replace {{VERSION}} with the provided version number
|
||||||
|
find src/ -type f -name "*.md" -exec sed -i "s/{{VERSION}}/$VERSION/g" {} \;
|
||||||
@@ -14,7 +14,7 @@ on the `data` and `letsencrypt` folders at startup.
|
|||||||
```yml
|
```yml
|
||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
image: 'jc21/nginx-proxy-manager:latest'
|
image: 'jc21/nginx-proxy-manager:{{VERSION}}'
|
||||||
environment:
|
environment:
|
||||||
PUID: 1000
|
PUID: 1000
|
||||||
PGID: 1000
|
PGID: 1000
|
||||||
@@ -101,7 +101,7 @@ secrets:
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
image: 'jc21/nginx-proxy-manager:latest'
|
image: 'jc21/nginx-proxy-manager:{{VERSION}}'
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
# Public HTTP Port:
|
# Public HTTP Port:
|
||||||
@@ -130,18 +130,16 @@ services:
|
|||||||
- db
|
- db
|
||||||
|
|
||||||
db:
|
db:
|
||||||
image: jc21/mariadb-aria
|
image: 'linuxserver/mariadb'
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
# MYSQL_ROOT_PASSWORD: "npm" # use secret instead
|
|
||||||
MYSQL_ROOT_PASSWORD__FILE: /run/secrets/DB_ROOT_PWD
|
MYSQL_ROOT_PASSWORD__FILE: /run/secrets/DB_ROOT_PWD
|
||||||
MYSQL_DATABASE: "npm"
|
MYSQL_DATABASE: 'npm'
|
||||||
MYSQL_USER: "npm"
|
MYSQL_USER: 'npm'
|
||||||
# MYSQL_PASSWORD: "npm" # use secret instead
|
|
||||||
MYSQL_PASSWORD__FILE: /run/secrets/MYSQL_PWD
|
MYSQL_PASSWORD__FILE: /run/secrets/MYSQL_PWD
|
||||||
MARIADB_AUTO_UPGRADE: '1'
|
TZ: 'Australia/Brisbane'
|
||||||
volumes:
|
volumes:
|
||||||
- ./mysql:/var/lib/mysql
|
- ./mariadb:/config
|
||||||
secrets:
|
secrets:
|
||||||
- DB_ROOT_PWD
|
- DB_ROOT_PWD
|
||||||
- MYSQL_PWD
|
- MYSQL_PWD
|
||||||
@@ -233,8 +231,20 @@ load_module /usr/lib/nginx/modules/ngx_stream_geoip2_module.so;
|
|||||||
|
|
||||||
Setting these environment variables will create the default user on startup, skipping the UI first user setup screen:
|
Setting these environment variables will create the default user on startup, skipping the UI first user setup screen:
|
||||||
|
|
||||||
```
|
```yml
|
||||||
environment:
|
environment:
|
||||||
INITIAL_ADMIN_EMAIL: my@example.com
|
INITIAL_ADMIN_EMAIL: my@example.com
|
||||||
INITIAL_ADMIN_PASSWORD: mypassword1
|
INITIAL_ADMIN_PASSWORD: mypassword1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Disable Nginx Resolver
|
||||||
|
|
||||||
|
On startup, we generate a resolvers directive for Nginx unless this is defined:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
environment:
|
||||||
|
DISABLE_RESOLVER: true
|
||||||
|
```
|
||||||
|
|
||||||
|
In this configuration, all DNS queries performed by Nginx will fall to the `/etc/hosts` file
|
||||||
|
and then the `/etc/resolv.conf`.
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ I won't go in to too much detail here but here are the basics for someone new to
|
|||||||
```yml
|
```yml
|
||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
image: 'jc21/nginx-proxy-manager:latest'
|
image: 'jc21/nginx-proxy-manager:{{VERSION}}'
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
TZ: "Australia/Brisbane"
|
TZ: "Australia/Brisbane"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ Create a `docker-compose.yml` file:
|
|||||||
```yml
|
```yml
|
||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
image: 'jc21/nginx-proxy-manager:latest'
|
image: 'jc21/nginx-proxy-manager:{{VERSION}}'
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
@@ -45,10 +45,7 @@ docker compose up -d
|
|||||||
|
|
||||||
## Using MySQL / MariaDB Database
|
## Using MySQL / MariaDB Database
|
||||||
|
|
||||||
If you opt for the MySQL configuration you will have to provide the database server yourself. You can also use MariaDB. Here are the minimum supported versions:
|
If you opt for the MySQL configuration you will have to provide the database server yourself.
|
||||||
|
|
||||||
- MySQL v5.7.8+
|
|
||||||
- MariaDB v10.2.7+
|
|
||||||
|
|
||||||
It's easy to use another docker container for your database also and link it as part of the docker stack, so that's what the following examples
|
It's easy to use another docker container for your database also and link it as part of the docker stack, so that's what the following examples
|
||||||
are going to use.
|
are going to use.
|
||||||
@@ -58,7 +55,7 @@ Here is an example of what your `docker-compose.yml` will look like when using a
|
|||||||
```yml
|
```yml
|
||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
image: 'jc21/nginx-proxy-manager:latest'
|
image: 'jc21/nginx-proxy-manager:{{VERSION}}'
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
# These ports are in format <host-port>:<container-port>
|
# These ports are in format <host-port>:<container-port>
|
||||||
@@ -88,31 +85,29 @@ services:
|
|||||||
- db
|
- db
|
||||||
|
|
||||||
db:
|
db:
|
||||||
image: 'jc21/mariadb-aria:latest'
|
image: 'linuxserver/mariadb'
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: 'npm'
|
MYSQL_ROOT_PASSWORD: 'npm'
|
||||||
MYSQL_DATABASE: 'npm'
|
MYSQL_DATABASE: 'npm'
|
||||||
MYSQL_USER: 'npm'
|
MYSQL_USER: 'npm'
|
||||||
MYSQL_PASSWORD: 'npm'
|
MYSQL_PASSWORD: 'npm'
|
||||||
MARIADB_AUTO_UPGRADE: '1'
|
TZ: 'Australia/Brisbane'
|
||||||
volumes:
|
volumes:
|
||||||
- ./mysql:/var/lib/mysql
|
- ./mariadb:/config
|
||||||
```
|
```
|
||||||
|
|
||||||
::: warning
|
::: warning
|
||||||
|
|
||||||
Please note, that `DB_MYSQL_*` environment variables will take precedent over `DB_SQLITE_*` variables. So if you keep the MySQL variables, you will not be able to use SQLite.
|
Please note, that `DB_MYSQL_*` environment variables will take precedent over `DB_SQLITE_*` variables. So if you keep the MySQL variables, you will not be able to use SQLite.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### Optional: MySQL / MariaDB SSL
|
### Optional: MySQL / MariaDB SSL
|
||||||
|
|
||||||
You can enable TLS for the MySQL/MariaDB connection with these environment variables:
|
You can enable TLS for the MySQL/MariaDB connection with these environment variables:
|
||||||
|
|
||||||
- DB_MYSQL_SSL: Enable SSL when set to true. If unset or false, SSL disabled (previous default behaviour).
|
- `DB_MYSQL_SSL`: Enable SSL when set to true. If unset or false, SSL disabled (previous default behaviour).
|
||||||
- DB_MYSQL_SSL_REJECT_UNAUTHORIZED: (default: true) Validate the server certificate chain. Set to false to allow self‑signed/unknown CA.
|
- `DB_MYSQL_SSL_REJECT_UNAUTHORIZED`: (default: true) Validate the server certificate chain. Set to false to allow self‑signed/unknown CA.
|
||||||
- DB_MYSQL_SSL_VERIFY_IDENTITY: (default: true) Performs host name / identity verification.
|
- `DB_MYSQL_SSL_VERIFY_IDENTITY`: (default: true) Performs host name / identity verification.
|
||||||
|
|
||||||
Enabling SSL using a self-signed cert (not recommended for production).
|
Enabling SSL using a self-signed cert (not recommended for production).
|
||||||
|
|
||||||
@@ -123,7 +118,7 @@ Similar to the MySQL server setup:
|
|||||||
```yml
|
```yml
|
||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
image: 'jc21/nginx-proxy-manager:latest'
|
image: 'jc21/nginx-proxy-manager:{{VERSION}}'
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
# These ports are in format <host-port>:<container-port>
|
# These ports are in format <host-port>:<container-port>
|
||||||
@@ -169,7 +164,11 @@ Custom Postgres schema is not supported, as such `public` will be used.
|
|||||||
The docker images support the following architectures:
|
The docker images support the following architectures:
|
||||||
- amd64
|
- amd64
|
||||||
- arm64
|
- arm64
|
||||||
- armv7
|
|
||||||
|
::: warning
|
||||||
|
`armv7` is no longer supported in version 2.14+. This is due to Nodejs dropping support for armhf. Please
|
||||||
|
use the `2.13.7` image tag if this applies to you.
|
||||||
|
:::
|
||||||
|
|
||||||
The docker images are a manifest of all the architecture docker builds supported, so this means
|
The docker images are a manifest of all the architecture docker builds supported, so this means
|
||||||
you don't have to worry about doing anything special and you can follow the common instructions above.
|
you don't have to worry about doing anything special and you can follow the common instructions above.
|
||||||
@@ -181,8 +180,6 @@ for a list of supported architectures and if you want one that doesn't exist,
|
|||||||
Also, if you don't know how to already, follow [this guide to install docker and docker-compose](https://manre-universe.net/how-to-run-docker-and-docker-compose-on-raspbian/)
|
Also, if you don't know how to already, follow [this guide to install docker and docker-compose](https://manre-universe.net/how-to-run-docker-and-docker-compose-on-raspbian/)
|
||||||
on Raspbian.
|
on Raspbian.
|
||||||
|
|
||||||
Please note that the `jc21/mariadb-aria:latest` image might have some problems on some ARM devices, if you want a separate database container, use the `yobasystems/alpine-mariadb:latest` image.
|
|
||||||
|
|
||||||
## Initial Run
|
## Initial Run
|
||||||
|
|
||||||
After the app is running for the first time, the following will happen:
|
After the app is running for the first time, the following will happen:
|
||||||
|
|||||||
230
docs/yarn.lock
230
docs/yarn.lock
@@ -335,85 +335,130 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba"
|
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba"
|
||||||
integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
|
integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
|
||||||
|
|
||||||
"@rollup/rollup-android-arm-eabi@4.24.0":
|
"@rollup/rollup-android-arm-eabi@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz#1661ff5ea9beb362795304cb916049aba7ac9c54"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz#a6742c74c7d9d6d604ef8a48f99326b4ecda3d82"
|
||||||
integrity sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==
|
integrity sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==
|
||||||
|
|
||||||
"@rollup/rollup-android-arm64@4.24.0":
|
"@rollup/rollup-android-arm64@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz#2ffaa91f1b55a0082b8a722525741aadcbd3971e"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz#97247be098de4df0c11971089fd2edf80a5da8cf"
|
||||||
integrity sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==
|
integrity sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==
|
||||||
|
|
||||||
"@rollup/rollup-darwin-arm64@4.24.0":
|
"@rollup/rollup-darwin-arm64@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz#627007221b24b8cc3063703eee0b9177edf49c1f"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz#674852cf14cf11b8056e0b1a2f4e872b523576cf"
|
||||||
integrity sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==
|
integrity sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==
|
||||||
|
|
||||||
"@rollup/rollup-darwin-x64@4.24.0":
|
"@rollup/rollup-darwin-x64@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz#0605506142b9e796c370d59c5984ae95b9758724"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz#36dfd7ed0aaf4d9d89d9ef983af72632455b0246"
|
||||||
integrity sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==
|
integrity sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==
|
||||||
|
|
||||||
"@rollup/rollup-linux-arm-gnueabihf@4.24.0":
|
"@rollup/rollup-freebsd-arm64@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz#62dfd196d4b10c0c2db833897164d2d319ee0cbb"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz#2f87c2074b4220260fdb52a9996246edfc633c22"
|
||||||
integrity sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==
|
integrity sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==
|
||||||
|
|
||||||
"@rollup/rollup-linux-arm-musleabihf@4.24.0":
|
"@rollup/rollup-freebsd-x64@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz#53ce72aeb982f1f34b58b380baafaf6a240fddb3"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz#9b5a26522a38a95dc06616d1939d4d9a76937803"
|
||||||
integrity sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==
|
integrity sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==
|
||||||
|
|
||||||
"@rollup/rollup-linux-arm64-gnu@4.24.0":
|
"@rollup/rollup-linux-arm-gnueabihf@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz#1632990f62a75c74f43e4b14ab3597d7ed416496"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz#86aa4859385a8734235b5e40a48e52d770758c3a"
|
||||||
integrity sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==
|
integrity sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==
|
||||||
|
|
||||||
"@rollup/rollup-linux-arm64-musl@4.24.0":
|
"@rollup/rollup-linux-arm-musleabihf@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz#8c03a996efb41e257b414b2e0560b7a21f2d9065"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz#cbe70e56e6ece8dac83eb773b624fc9e5a460976"
|
||||||
integrity sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==
|
integrity sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==
|
||||||
|
|
||||||
"@rollup/rollup-linux-powerpc64le-gnu@4.24.0":
|
"@rollup/rollup-linux-arm64-gnu@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz#5b98729628d5bcc8f7f37b58b04d6845f85c7b5d"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz#d14992a2e653bc3263d284bc6579b7a2890e1c45"
|
||||||
integrity sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==
|
integrity sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==
|
||||||
|
|
||||||
"@rollup/rollup-linux-riscv64-gnu@4.24.0":
|
"@rollup/rollup-linux-arm64-musl@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz#48e42e41f4cabf3573cfefcb448599c512e22983"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz#2fdd1ddc434ea90aeaa0851d2044789b4d07f6da"
|
||||||
integrity sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==
|
integrity sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==
|
||||||
|
|
||||||
"@rollup/rollup-linux-s390x-gnu@4.24.0":
|
"@rollup/rollup-linux-loong64-gnu@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz#e0b4f9a966872cb7d3e21b9e412a4b7efd7f0b58"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz#8a181e6f89f969f21666a743cd411416c80099e7"
|
||||||
integrity sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==
|
integrity sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==
|
||||||
|
|
||||||
"@rollup/rollup-linux-x64-gnu@4.24.0":
|
"@rollup/rollup-linux-loong64-musl@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz#78144741993100f47bd3da72fce215e077ae036b"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz#904125af2babc395f8061daa27b5af1f4e3f2f78"
|
||||||
integrity sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==
|
integrity sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==
|
||||||
|
|
||||||
"@rollup/rollup-linux-x64-musl@4.24.0":
|
"@rollup/rollup-linux-ppc64-gnu@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz#d9fe32971883cd1bd858336bd33a1c3ca6146127"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz#a57970ac6864c9a3447411a658224bdcf948be22"
|
||||||
integrity sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==
|
integrity sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==
|
||||||
|
|
||||||
"@rollup/rollup-win32-arm64-msvc@4.24.0":
|
"@rollup/rollup-linux-ppc64-musl@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz#71fa3ea369316db703a909c790743972e98afae5"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz#bb84de5b26870567a4267666e08891e80bb56a63"
|
||||||
integrity sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==
|
integrity sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==
|
||||||
|
|
||||||
"@rollup/rollup-win32-ia32-msvc@4.24.0":
|
"@rollup/rollup-linux-riscv64-gnu@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz#653f5989a60658e17d7576a3996deb3902e342e2"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz#72d00d2c7fb375ce3564e759db33f17a35bffab9"
|
||||||
integrity sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==
|
integrity sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==
|
||||||
|
|
||||||
"@rollup/rollup-win32-x64-msvc@4.24.0":
|
"@rollup/rollup-linux-riscv64-musl@4.59.0":
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz#0574d7e87b44ee8511d08cc7f914bcb802b70818"
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz#4c166ef58e718f9245bd31873384ba15a5c1a883"
|
||||||
integrity sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==
|
integrity sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-s390x-gnu@4.59.0":
|
||||||
|
version "4.59.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz#bb5025cde9a61db478c2ca7215808ad3bce73a09"
|
||||||
|
integrity sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-gnu@4.59.0":
|
||||||
|
version "4.59.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz#9b66b1f9cd95c6624c788f021c756269ffed1552"
|
||||||
|
integrity sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-musl@4.59.0":
|
||||||
|
version "4.59.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz#b007ca255dc7166017d57d7d2451963f0bd23fd9"
|
||||||
|
integrity sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==
|
||||||
|
|
||||||
|
"@rollup/rollup-openbsd-x64@4.59.0":
|
||||||
|
version "4.59.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz#e8b357b2d1aa2c8d76a98f5f0d889eabe93f4ef9"
|
||||||
|
integrity sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==
|
||||||
|
|
||||||
|
"@rollup/rollup-openharmony-arm64@4.59.0":
|
||||||
|
version "4.59.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz#96c2e3f4aacd3d921981329831ff8dde492204dc"
|
||||||
|
integrity sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-arm64-msvc@4.59.0":
|
||||||
|
version "4.59.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz#2d865149d706d938df8b4b8f117e69a77646d581"
|
||||||
|
integrity sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-ia32-msvc@4.59.0":
|
||||||
|
version "4.59.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz#abe1593be0fa92325e9971c8da429c5e05b92c36"
|
||||||
|
integrity sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-x64-gnu@4.59.0":
|
||||||
|
version "4.59.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz#c4af3e9518c9a5cd4b1c163dc81d0ad4d82e7eab"
|
||||||
|
integrity sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-x64-msvc@4.59.0":
|
||||||
|
version "4.59.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz#4584a8a87b29188a4c1fe987a9fcf701e256d86c"
|
||||||
|
integrity sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==
|
||||||
|
|
||||||
"@shikijs/core@2.5.0", "@shikijs/core@^2.1.0":
|
"@shikijs/core@2.5.0", "@shikijs/core@^2.1.0":
|
||||||
version "2.5.0"
|
version "2.5.0"
|
||||||
@@ -479,10 +524,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz#a90ab31d0cc1dfb54c66a69e515bf624fa7b2224"
|
resolved "https://registry.yarnpkg.com/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz#a90ab31d0cc1dfb54c66a69e515bf624fa7b2224"
|
||||||
integrity sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==
|
integrity sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==
|
||||||
|
|
||||||
"@types/estree@1.0.6":
|
"@types/estree@1.0.8":
|
||||||
version "1.0.6"
|
version "1.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
|
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e"
|
||||||
integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
|
integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==
|
||||||
|
|
||||||
"@types/hast@^3.0.0", "@types/hast@^3.0.4":
|
"@types/hast@^3.0.0", "@types/hast@^3.0.4":
|
||||||
version "3.0.4"
|
version "3.0.4"
|
||||||
@@ -994,28 +1039,37 @@ rfdc@^1.4.1:
|
|||||||
integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==
|
integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==
|
||||||
|
|
||||||
rollup@^4.20.0:
|
rollup@^4.20.0:
|
||||||
version "4.24.0"
|
version "4.59.0"
|
||||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.24.0.tgz#c14a3576f20622ea6a5c9cad7caca5e6e9555d05"
|
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.59.0.tgz#cf74edac17c1486f562d728a4d923a694abdf06f"
|
||||||
integrity sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==
|
integrity sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/estree" "1.0.6"
|
"@types/estree" "1.0.8"
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
"@rollup/rollup-android-arm-eabi" "4.24.0"
|
"@rollup/rollup-android-arm-eabi" "4.59.0"
|
||||||
"@rollup/rollup-android-arm64" "4.24.0"
|
"@rollup/rollup-android-arm64" "4.59.0"
|
||||||
"@rollup/rollup-darwin-arm64" "4.24.0"
|
"@rollup/rollup-darwin-arm64" "4.59.0"
|
||||||
"@rollup/rollup-darwin-x64" "4.24.0"
|
"@rollup/rollup-darwin-x64" "4.59.0"
|
||||||
"@rollup/rollup-linux-arm-gnueabihf" "4.24.0"
|
"@rollup/rollup-freebsd-arm64" "4.59.0"
|
||||||
"@rollup/rollup-linux-arm-musleabihf" "4.24.0"
|
"@rollup/rollup-freebsd-x64" "4.59.0"
|
||||||
"@rollup/rollup-linux-arm64-gnu" "4.24.0"
|
"@rollup/rollup-linux-arm-gnueabihf" "4.59.0"
|
||||||
"@rollup/rollup-linux-arm64-musl" "4.24.0"
|
"@rollup/rollup-linux-arm-musleabihf" "4.59.0"
|
||||||
"@rollup/rollup-linux-powerpc64le-gnu" "4.24.0"
|
"@rollup/rollup-linux-arm64-gnu" "4.59.0"
|
||||||
"@rollup/rollup-linux-riscv64-gnu" "4.24.0"
|
"@rollup/rollup-linux-arm64-musl" "4.59.0"
|
||||||
"@rollup/rollup-linux-s390x-gnu" "4.24.0"
|
"@rollup/rollup-linux-loong64-gnu" "4.59.0"
|
||||||
"@rollup/rollup-linux-x64-gnu" "4.24.0"
|
"@rollup/rollup-linux-loong64-musl" "4.59.0"
|
||||||
"@rollup/rollup-linux-x64-musl" "4.24.0"
|
"@rollup/rollup-linux-ppc64-gnu" "4.59.0"
|
||||||
"@rollup/rollup-win32-arm64-msvc" "4.24.0"
|
"@rollup/rollup-linux-ppc64-musl" "4.59.0"
|
||||||
"@rollup/rollup-win32-ia32-msvc" "4.24.0"
|
"@rollup/rollup-linux-riscv64-gnu" "4.59.0"
|
||||||
"@rollup/rollup-win32-x64-msvc" "4.24.0"
|
"@rollup/rollup-linux-riscv64-musl" "4.59.0"
|
||||||
|
"@rollup/rollup-linux-s390x-gnu" "4.59.0"
|
||||||
|
"@rollup/rollup-linux-x64-gnu" "4.59.0"
|
||||||
|
"@rollup/rollup-linux-x64-musl" "4.59.0"
|
||||||
|
"@rollup/rollup-openbsd-x64" "4.59.0"
|
||||||
|
"@rollup/rollup-openharmony-arm64" "4.59.0"
|
||||||
|
"@rollup/rollup-win32-arm64-msvc" "4.59.0"
|
||||||
|
"@rollup/rollup-win32-ia32-msvc" "4.59.0"
|
||||||
|
"@rollup/rollup-win32-x64-gnu" "4.59.0"
|
||||||
|
"@rollup/rollup-win32-x64-msvc" "4.59.0"
|
||||||
fsevents "~2.3.2"
|
fsevents "~2.3.2"
|
||||||
|
|
||||||
shiki@^2.1.0:
|
shiki@^2.1.0:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://biomejs.dev/schemas/2.3.2/schema.json",
|
"$schema": "https://biomejs.dev/schemas/2.4.5/schema.json",
|
||||||
"vcs": {
|
"vcs": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"clientKind": "git",
|
"clientKind": "git",
|
||||||
|
|||||||
@@ -9,23 +9,28 @@
|
|||||||
const allLocales = [
|
const allLocales = [
|
||||||
["en", "en-US"],
|
["en", "en-US"],
|
||||||
["de", "de-DE"],
|
["de", "de-DE"],
|
||||||
|
["pt", "pt-PT"],
|
||||||
["es", "es-ES"],
|
["es", "es-ES"],
|
||||||
|
["et", "et-EE"],
|
||||||
|
["fr", "fr-FR"],
|
||||||
["it", "it-IT"],
|
["it", "it-IT"],
|
||||||
["ja", "ja-JP"],
|
["ja", "ja-JP"],
|
||||||
["nl", "nl-NL"],
|
["nl", "nl-NL"],
|
||||||
["pl", "pl-PL"],
|
["pl", "pl-PL"],
|
||||||
["ru", "ru-RU"],
|
["ru", "ru-RU"],
|
||||||
["sk", "sk-SK"],
|
["sk", "sk-SK"],
|
||||||
|
["cs", "cs-CZ"],
|
||||||
["vi", "vi-VN"],
|
["vi", "vi-VN"],
|
||||||
["zh", "zh-CN"],
|
["zh", "zh-CN"],
|
||||||
["ko", "ko-KR"],
|
["ko", "ko-KR"],
|
||||||
["bg", "bg-BG"],
|
["bg", "bg-BG"],
|
||||||
["id", "id-ID"],
|
["id", "id-ID"],
|
||||||
|
["tr", "tr-TR"],
|
||||||
|
["hu", "hu-HU"],
|
||||||
|
["no", "no-NO"],
|
||||||
];
|
];
|
||||||
|
|
||||||
const ignoreUnused = [
|
const ignoreUnused = [/^.*$/];
|
||||||
/^.*$/,
|
|
||||||
];
|
|
||||||
|
|
||||||
const { spawnSync } = require("child_process");
|
const { spawnSync } = require("child_process");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
@@ -68,9 +73,7 @@ const allKeys = [];
|
|||||||
const checkLangList = (fullCode) => {
|
const checkLangList = (fullCode) => {
|
||||||
const key = "locale-" + fullCode;
|
const key = "locale-" + fullCode;
|
||||||
if (typeof langList[key] === "undefined") {
|
if (typeof langList[key] === "undefined") {
|
||||||
allErrors.push(
|
allErrors.push("ERROR: `" + key + "` language does not exist in lang-list.json");
|
||||||
"ERROR: `" + key + "` language does not exist in lang-list.json",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -79,18 +82,14 @@ const compareLocale = (locale) => {
|
|||||||
// Check that locale contains the items used in the codebase
|
// Check that locale contains the items used in the codebase
|
||||||
projectLocaleKeys.map((key) => {
|
projectLocaleKeys.map((key) => {
|
||||||
if (typeof locale.data[key] === "undefined") {
|
if (typeof locale.data[key] === "undefined") {
|
||||||
allErrors.push(
|
allErrors.push("ERROR: `" + locale[0] + "` does not contain item: `" + key + "`");
|
||||||
"ERROR: `" + locale[0] + "` does not contain item: `" + key + "`",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
// Check that locale contains all error.* items
|
// Check that locale contains all error.* items
|
||||||
BACKEND_ERRORS.forEach((key) => {
|
BACKEND_ERRORS.forEach((key) => {
|
||||||
if (typeof locale.data[key] === "undefined") {
|
if (typeof locale.data[key] === "undefined") {
|
||||||
allErrors.push(
|
allErrors.push("ERROR: `" + locale[0] + "` does not contain item: `" + key + "`");
|
||||||
"ERROR: `" + locale[0] + "` does not contain item: `" + key + "`",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
@@ -109,9 +108,7 @@ const compareLocale = (locale) => {
|
|||||||
if (!ignored && typeof allLocalesInProject[key] === "undefined") {
|
if (!ignored && typeof allLocalesInProject[key] === "undefined") {
|
||||||
// ensure this key doesn't exist in the backend errors either
|
// ensure this key doesn't exist in the backend errors either
|
||||||
if (!BACKEND_ERRORS.includes(key)) {
|
if (!BACKEND_ERRORS.includes(key)) {
|
||||||
allErrors.push(
|
allErrors.push("ERROR: `" + locale[0] + "` contains unused item: `" + key + "`");
|
||||||
"ERROR: `" + locale[0] + "` contains unused item: `" + key + "`",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,9 +125,7 @@ const compareLocale = (locale) => {
|
|||||||
const checkForMissing = (locale) => {
|
const checkForMissing = (locale) => {
|
||||||
allKeys.forEach((key) => {
|
allKeys.forEach((key) => {
|
||||||
if (typeof locale.data[key] === "undefined") {
|
if (typeof locale.data[key] === "undefined") {
|
||||||
allWarnings.push(
|
allWarnings.push("WARN: `" + locale[0] + "` does not contain item: `" + key + "`");
|
||||||
"WARN: `" + locale[0] + "` does not contain item: `" + key + "`",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<title>Nginx Proxy Manager</title>
|
<title>Nginx Proxy Manager</title>
|
||||||
<meta name="description" content="In The Office Planner" />
|
<meta name="description" content="Manage Nginx hosts with a simple, powerful interface" />
|
||||||
<link rel="preload" href="/images/logo-no-text.svg" as="image" type="image/svg+xml" fetchPriority="high">
|
<link rel="preload" href="/images/logo-no-text.svg" as="image" type="image/svg+xml" fetchPriority="high">
|
||||||
<link
|
<link
|
||||||
rel="apple-touch-icon"
|
rel="apple-touch-icon"
|
||||||
|
|||||||
@@ -17,50 +17,50 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tabler/core": "^1.4.0",
|
"@tabler/core": "^1.4.0",
|
||||||
"@tabler/icons-react": "^3.35.0",
|
"@tabler/icons-react": "^3.38.0",
|
||||||
"@tanstack/react-query": "^5.90.6",
|
"@tanstack/react-query": "^5.90.21",
|
||||||
"@tanstack/react-table": "^8.21.3",
|
"@tanstack/react-table": "^8.21.3",
|
||||||
"@uiw/react-textarea-code-editor": "^3.1.1",
|
"@uiw/react-textarea-code-editor": "^3.1.1",
|
||||||
"classnames": "^2.5.1",
|
"classnames": "^2.5.1",
|
||||||
"country-flag-icons": "^1.5.21",
|
"country-flag-icons": "^1.6.15",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"ez-modal-react": "^1.0.5",
|
"ez-modal-react": "^1.0.5",
|
||||||
"formik": "^2.4.6",
|
"formik": "^2.4.9",
|
||||||
"generate-password-browser": "^1.1.0",
|
"generate-password-browser": "^1.1.0",
|
||||||
"humps": "^2.0.1",
|
"humps": "^2.0.1",
|
||||||
"query-string": "^9.3.1",
|
"query-string": "^9.3.1",
|
||||||
"react": "^19.2.3",
|
"react": "^19.2.4",
|
||||||
"react-bootstrap": "^2.10.10",
|
"react-bootstrap": "^2.10.10",
|
||||||
"react-dom": "^19.2.3",
|
"react-dom": "^19.2.4",
|
||||||
"react-intl": "^7.1.14",
|
"react-intl": "^8.1.3",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"react-router-dom": "^7.9.5",
|
"react-router-dom": "^7.13.1",
|
||||||
"react-select": "^5.10.2",
|
"react-select": "^5.10.2",
|
||||||
"react-toastify": "^11.0.5",
|
"react-toastify": "^11.0.5",
|
||||||
"rooks": "^9.3.0"
|
"rooks": "^9.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^2.3.2",
|
"@biomejs/biome": "^2.4.5",
|
||||||
"@formatjs/cli": "^6.7.4",
|
"@formatjs/cli": "^6.13.0",
|
||||||
"@tanstack/react-query-devtools": "^5.90.2",
|
"@tanstack/react-query-devtools": "^5.91.3",
|
||||||
"@testing-library/dom": "^10.4.1",
|
"@testing-library/dom": "^10.4.1",
|
||||||
"@testing-library/jest-dom": "^6.9.1",
|
"@testing-library/jest-dom": "^6.9.1",
|
||||||
"@testing-library/react": "^16.3.0",
|
"@testing-library/react": "^16.3.2",
|
||||||
"@types/country-flag-icons": "^1.2.2",
|
"@types/country-flag-icons": "^1.2.2",
|
||||||
"@types/humps": "^2.0.6",
|
"@types/humps": "^2.0.6",
|
||||||
"@types/react": "^19.2.7",
|
"@types/react": "^19.2.14",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@types/react-table": "^7.7.20",
|
"@types/react-table": "^7.7.20",
|
||||||
"@vitejs/plugin-react": "^5.1.2",
|
"@vitejs/plugin-react": "^5.1.4",
|
||||||
"happy-dom": "^20.0.10",
|
"happy-dom": "^20.8.3",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.8",
|
||||||
"postcss-simple-vars": "^7.0.1",
|
"postcss-simple-vars": "^7.0.1",
|
||||||
"sass": "^1.93.3",
|
"sass": "^1.97.3",
|
||||||
"tmp": "^0.2.5",
|
"tmp": "^0.2.5",
|
||||||
"typescript": "5.9.3",
|
"typescript": "5.9.3",
|
||||||
"vite": "^7.1.12",
|
"vite": "^7.3.1",
|
||||||
"vite-plugin-checker": "^0.11.0",
|
"vite-plugin-checker": "^0.12.0",
|
||||||
"vite-tsconfig-paths": "^5.1.4",
|
"vite-tsconfig-paths": "^6.1.1",
|
||||||
"vitest": "^4.0.6"
|
"vitest": "^4.0.18"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ export interface ProxyHost {
|
|||||||
locations?: ProxyLocation[];
|
locations?: ProxyLocation[];
|
||||||
hstsEnabled: boolean;
|
hstsEnabled: boolean;
|
||||||
hstsSubdomains: boolean;
|
hstsSubdomains: boolean;
|
||||||
|
trustForwardedProto: boolean;
|
||||||
// Expansions:
|
// Expansions:
|
||||||
owner?: User;
|
owner?: User;
|
||||||
accessList?: AccessList;
|
accessList?: AccessList;
|
||||||
|
|||||||
@@ -5,17 +5,18 @@ import { T } from "src/locale";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
forHttp?: boolean; // the sslForced, http2Support, hstsEnabled, hstsSubdomains fields
|
forHttp?: boolean; // the sslForced, http2Support, hstsEnabled, hstsSubdomains fields
|
||||||
|
forProxyHost?: boolean; // the advanced fields
|
||||||
forceDNSForNew?: boolean;
|
forceDNSForNew?: boolean;
|
||||||
requireDomainNames?: boolean; // used for streams
|
requireDomainNames?: boolean; // used for streams
|
||||||
color?: string;
|
color?: string;
|
||||||
}
|
}
|
||||||
export function SSLOptionsFields({ forHttp = true, forceDNSForNew, requireDomainNames, color = "bg-cyan" }: Props) {
|
export function SSLOptionsFields({ forHttp = true, forProxyHost = false, forceDNSForNew, requireDomainNames, color = "bg-cyan" }: Props) {
|
||||||
const { values, setFieldValue } = useFormikContext();
|
const { values, setFieldValue } = useFormikContext();
|
||||||
const v: any = values || {};
|
const v: any = values || {};
|
||||||
|
|
||||||
const newCertificate = v?.certificateId === "new";
|
const newCertificate = v?.certificateId === "new";
|
||||||
const hasCertificate = newCertificate || (v?.certificateId && v?.certificateId > 0);
|
const hasCertificate = newCertificate || (v?.certificateId && v?.certificateId > 0);
|
||||||
const { sslForced, http2Support, hstsEnabled, hstsSubdomains, meta } = v;
|
const { sslForced, http2Support, hstsEnabled, hstsSubdomains, trustForwardedProto, meta } = v;
|
||||||
const { dnsChallenge } = meta || {};
|
const { dnsChallenge } = meta || {};
|
||||||
|
|
||||||
if (forceDNSForNew && newCertificate && !dnsChallenge) {
|
if (forceDNSForNew && newCertificate && !dnsChallenge) {
|
||||||
@@ -115,6 +116,34 @@ export function SSLOptionsFields({ forHttp = true, forceDNSForNew, requireDomain
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const getHttpAdvancedOptions = () =>(
|
||||||
|
<div>
|
||||||
|
<details>
|
||||||
|
<summary className="mb-1"><T id="domains.advanced" /></summary>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<Field name="trustForwardedProto">
|
||||||
|
{({ field }: any) => (
|
||||||
|
<label className="form-check form-switch mt-1">
|
||||||
|
<input
|
||||||
|
className={trustForwardedProto ? toggleEnabled : toggleClasses}
|
||||||
|
type="checkbox"
|
||||||
|
checked={!!trustForwardedProto}
|
||||||
|
onChange={(e) => handleToggleChange(e, field.name)}
|
||||||
|
disabled={!hasCertificate || !sslForced}
|
||||||
|
/>
|
||||||
|
<span className="form-check-label">
|
||||||
|
<T id="domains.trust-forwarded-proto" />
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{forHttp ? getHttpOptions() : null}
|
{forHttp ? getHttpOptions() : null}
|
||||||
@@ -140,6 +169,7 @@ export function SSLOptionsFields({ forHttp = true, forceDNSForNew, requireDomain
|
|||||||
{dnsChallenge ? <DNSProviderFields showBoundaryBox /> : null}
|
{dnsChallenge ? <DNSProviderFields showBoundaryBox /> : null}
|
||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
|
{forProxyHost && forHttp ? getHttpAdvancedOptions() : null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const fetchProxyHost = (id: number | "new") => {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
hstsEnabled: false,
|
hstsEnabled: false,
|
||||||
hstsSubdomains: false,
|
hstsSubdomains: false,
|
||||||
|
trustForwardedProto: false,
|
||||||
} as ProxyHost);
|
} as ProxyHost);
|
||||||
}
|
}
|
||||||
return getProxyHost(id, ["owner"]);
|
return getProxyHost(id, ["owner"]);
|
||||||
|
|||||||
@@ -1,20 +1,27 @@
|
|||||||
import { createIntl, createIntlCache } from "react-intl";
|
import { createIntl, createIntlCache } from "react-intl";
|
||||||
|
import langBg from "./lang/bg.json";
|
||||||
import langDe from "./lang/de.json";
|
import langDe from "./lang/de.json";
|
||||||
|
import langPt from "./lang/pt.json";
|
||||||
import langEn from "./lang/en.json";
|
import langEn from "./lang/en.json";
|
||||||
import langEs from "./lang/es.json";
|
import langEs from "./lang/es.json";
|
||||||
|
import langEt from "./lang/et.json";
|
||||||
|
import langFr from "./lang/fr.json";
|
||||||
import langGa from "./lang/ga.json";
|
import langGa from "./lang/ga.json";
|
||||||
|
import langId from "./lang/id.json";
|
||||||
import langIt from "./lang/it.json";
|
import langIt from "./lang/it.json";
|
||||||
import langJa from "./lang/ja.json";
|
import langJa from "./lang/ja.json";
|
||||||
import langList from "./lang/lang-list.json";
|
import langKo from "./lang/ko.json";
|
||||||
import langNl from "./lang/nl.json";
|
import langNl from "./lang/nl.json";
|
||||||
import langPl from "./lang/pl.json";
|
import langPl from "./lang/pl.json";
|
||||||
import langRu from "./lang/ru.json";
|
import langRu from "./lang/ru.json";
|
||||||
import langSk from "./lang/sk.json";
|
import langSk from "./lang/sk.json";
|
||||||
|
import langCs from "./lang/cs.json";
|
||||||
import langVi from "./lang/vi.json";
|
import langVi from "./lang/vi.json";
|
||||||
import langZh from "./lang/zh.json";
|
import langZh from "./lang/zh.json";
|
||||||
import langKo from "./lang/ko.json";
|
import langTr from "./lang/tr.json";
|
||||||
import langBg from "./lang/bg.json";
|
import langHu from "./lang/hu.json";
|
||||||
import langId from "./lang/id.json";
|
import langNo from "./lang/no.json";
|
||||||
|
import langList from "./lang/lang-list.json";
|
||||||
|
|
||||||
// first item of each array should be the language code,
|
// first item of each array should be the language code,
|
||||||
// not the country code
|
// not the country code
|
||||||
@@ -23,6 +30,9 @@ const localeOptions = [
|
|||||||
["en", "en-US", langEn],
|
["en", "en-US", langEn],
|
||||||
["de", "de-DE", langDe],
|
["de", "de-DE", langDe],
|
||||||
["es", "es-ES", langEs],
|
["es", "es-ES", langEs],
|
||||||
|
["et", "et-EE", langEt],
|
||||||
|
["pt", "pt-PT", langPt],
|
||||||
|
["fr", "fr-FR", langFr],
|
||||||
["ga", "ga-IE", langGa],
|
["ga", "ga-IE", langGa],
|
||||||
["ja", "ja-JP", langJa],
|
["ja", "ja-JP", langJa],
|
||||||
["it", "it-IT", langIt],
|
["it", "it-IT", langIt],
|
||||||
@@ -30,11 +40,15 @@ const localeOptions = [
|
|||||||
["pl", "pl-PL", langPl],
|
["pl", "pl-PL", langPl],
|
||||||
["ru", "ru-RU", langRu],
|
["ru", "ru-RU", langRu],
|
||||||
["sk", "sk-SK", langSk],
|
["sk", "sk-SK", langSk],
|
||||||
|
["cs", "cs-CZ", langCs],
|
||||||
["vi", "vi-VN", langVi],
|
["vi", "vi-VN", langVi],
|
||||||
["zh", "zh-CN", langZh],
|
["zh", "zh-CN", langZh],
|
||||||
["ko", "ko-KR", langKo],
|
["ko", "ko-KR", langKo],
|
||||||
["bg", "bg-BG", langBg],
|
["bg", "bg-BG", langBg],
|
||||||
["id", "id-ID", langId],
|
["id", "id-ID", langId],
|
||||||
|
["tr", "tr-TR", langTr],
|
||||||
|
["hu", "hu-HU", langHu],
|
||||||
|
["no", "no-NO", langNo],
|
||||||
];
|
];
|
||||||
|
|
||||||
const loadMessages = (locale?: string): typeof langList & typeof langEn => {
|
const loadMessages = (locale?: string): typeof langList & typeof langEn => {
|
||||||
@@ -57,6 +71,7 @@ const getFlagCodeForLocale = (locale?: string) => {
|
|||||||
zh: "cn", // China
|
zh: "cn", // China
|
||||||
vi: "vn", // Vietnam
|
vi: "vn", // Vietnam
|
||||||
ko: "kr", // Korea
|
ko: "kr", // Korea
|
||||||
|
cs: "cz", // Czechia
|
||||||
};
|
};
|
||||||
|
|
||||||
if (specialCases[thisLocale]) {
|
if (specialCases[thisLocale]) {
|
||||||
@@ -123,6 +138,6 @@ const T = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("L:", localeOptions);
|
//console.log("L:", localeOptions);
|
||||||
|
|
||||||
export { localeOptions, getFlagCodeForLocale, getLocale, createIntl, changeLocale, intl, T };
|
export { localeOptions, getFlagCodeForLocale, getLocale, createIntl, changeLocale, intl, T };
|
||||||
|
|||||||
69
frontend/src/locale/scripts/locale-sort.cjs
Normal file
69
frontend/src/locale/scripts/locale-sort.cjs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const DIR = path.resolve(__dirname, "../src");
|
||||||
|
|
||||||
|
// Function to sort object keys recursively
|
||||||
|
function sortKeys(obj) {
|
||||||
|
if (obj === null || typeof obj !== "object" || obj instanceof Array) {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sorted = {};
|
||||||
|
const keys = Object.keys(obj).sort();
|
||||||
|
for (const key of keys) {
|
||||||
|
const value = obj[key];
|
||||||
|
if (typeof value === "object" && value !== null && !(value instanceof Array)) {
|
||||||
|
sorted[key] = sortKeys(value);
|
||||||
|
} else {
|
||||||
|
sorted[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sorted;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all JSON files in the directory
|
||||||
|
const files = fs.readdirSync(DIR).filter((file) => {
|
||||||
|
return file.endsWith(".json") && file !== "lang-list.json";
|
||||||
|
});
|
||||||
|
|
||||||
|
files.forEach((file) => {
|
||||||
|
const filePath = path.join(DIR, file);
|
||||||
|
const stats = fs.statSync(filePath);
|
||||||
|
|
||||||
|
if (!stats.isFile()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stats.size === 0) {
|
||||||
|
console.log(`Skipping empty file ${file}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Read original content
|
||||||
|
const originalContent = fs.readFileSync(filePath, "utf8");
|
||||||
|
const originalJson = JSON.parse(originalContent);
|
||||||
|
|
||||||
|
// Sort keys
|
||||||
|
const sortedJson = sortKeys(originalJson);
|
||||||
|
|
||||||
|
// Convert back to string with tabs
|
||||||
|
const sortedContent = JSON.stringify(sortedJson, null, "\t") + "\n";
|
||||||
|
|
||||||
|
// Compare (normalize whitespace)
|
||||||
|
if (originalContent.trim() === sortedContent.trim()) {
|
||||||
|
console.log(`${file} is already sorted`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write sorted content
|
||||||
|
fs.writeFileSync(filePath, sortedContent, "utf8");
|
||||||
|
console.log(`Sorted ${file}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error processing ${file}:`, error.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
7
frontend/src/locale/src/HelpDoc/cs/AccessLists.md
Normal file
7
frontend/src/locale/src/HelpDoc/cs/AccessLists.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## Co je seznam přístupů?
|
||||||
|
|
||||||
|
Seznamy přístupů poskytují blacklist nebo whitelist konkrétních IP adres klientů spolu s ověřením pro proxy hostitele prostřednictvím základního ověřování HTTP.
|
||||||
|
|
||||||
|
Můžete nakonfigurovat více pravidel pro klienty, uživatelská jména a hesla pro jeden seznam přístupu a poté ho použít na jednoho nebo více proxy hostitelů.
|
||||||
|
|
||||||
|
Toto je nejužitečnější pro přesměrované webové služby, které nemají vestavěné ověřovací mechanismy, nebo pokud se chcete chránit před neznámými klienty.
|
||||||
32
frontend/src/locale/src/HelpDoc/cs/Certificates.md
Normal file
32
frontend/src/locale/src/HelpDoc/cs/Certificates.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
## Pomoc s certifikáty
|
||||||
|
|
||||||
|
### Certifikát HTTP
|
||||||
|
|
||||||
|
Certifikát ověřený prostřednictvím protokolu HTTP znamená, že servery Let's Encrypt se
|
||||||
|
pokusí připojit k vašim doménám přes protokol HTTP (nikoli HTTPS!) a v případě úspěchu
|
||||||
|
vydají váš certifikát.
|
||||||
|
|
||||||
|
Pro tuto metodu budete muset mít pro své domény vytvořeného _Proxy Host_, který
|
||||||
|
je přístupný přes HTTP a směruje na tuto instalaci Nginx. Po vydání certifikátu
|
||||||
|
můžete změnit _Proxy Host_ tak, aby tento certifikát používal i pro HTTPS
|
||||||
|
připojení. _Proxy Host_ však bude stále potřeba nakonfigurovat pro přístup přes HTTP,
|
||||||
|
aby se certifikát mohl obnovit.
|
||||||
|
|
||||||
|
Tento proces _nepodporuje_ domény se zástupnými znaky.
|
||||||
|
|
||||||
|
### Certifikát DNS
|
||||||
|
|
||||||
|
Certifikát ověřený DNS vyžaduje použití pluginu DNS Provider. Tento DNS
|
||||||
|
Provider se použije na vytvoření dočasných záznamů ve vaší doméně a poté Let's
|
||||||
|
Encrypt ověří tyto záznamy, aby se ujistil, že jste vlastníkem, a pokud bude úspěšný,
|
||||||
|
vydá váš certifikát.
|
||||||
|
|
||||||
|
Před požádáním o tento typ certifikátu není potřeba vytvořit _Proxy Host_.
|
||||||
|
Není také potřeba mít _Proxy Host_ nakonfigurovaný pro přístup HTTP.
|
||||||
|
|
||||||
|
Tento proces _podporuje_ domény se zástupnými znaky.
|
||||||
|
|
||||||
|
### Vlastní certifikát
|
||||||
|
|
||||||
|
Tuto možnost použijte na nahrání vlastního SSL certifikátu, který vám poskytla vaše
|
||||||
|
certifikační autorita.
|
||||||
10
frontend/src/locale/src/HelpDoc/cs/DeadHosts.md
Normal file
10
frontend/src/locale/src/HelpDoc/cs/DeadHosts.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
## Co je to 404 Host?
|
||||||
|
|
||||||
|
404 Host je jednoduše nastavení hostitele, které zobrazuje stránku 404.
|
||||||
|
|
||||||
|
To může být užitečné, pokud je vaše doména uvedena ve vyhledávačích a chcete
|
||||||
|
poskytnout hezčí chybovou stránku nebo konkrétně oznámit vyhledávačům, že
|
||||||
|
stránky domény již neexistují.
|
||||||
|
|
||||||
|
Další výhodou tohoto hostitele je sledování protokolů o návštěvách a
|
||||||
|
zobrazení odkazů.
|
||||||
7
frontend/src/locale/src/HelpDoc/cs/ProxyHosts.md
Normal file
7
frontend/src/locale/src/HelpDoc/cs/ProxyHosts.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## Co je proxy hostitel?
|
||||||
|
|
||||||
|
Proxy hostitel je příchozí koncový bod pro webovou službu, kterou chcete přesměrovat.
|
||||||
|
|
||||||
|
Poskytuje volitelné ukončení SSL pro vaši službu, která nemusí mít zabudovanou podporu SSL.
|
||||||
|
|
||||||
|
Proxy hostitelé jsou nejběžnějším použitím pro Nginx Proxy Manager.
|
||||||
7
frontend/src/locale/src/HelpDoc/cs/RedirectionHosts.md
Normal file
7
frontend/src/locale/src/HelpDoc/cs/RedirectionHosts.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## Co je přesměrovací hostitel?
|
||||||
|
|
||||||
|
Přesměrovací hostitel přesměruje požadavky z příchozí domény a přesměruje
|
||||||
|
návštěvníka na jinou doménu.
|
||||||
|
|
||||||
|
Nejčastějším důvodem pro použití tohoto typu hostitele je situace, kdy vaše webová stránka změní
|
||||||
|
doménu, ale stále máte odkazy ve vyhledávačích nebo referenční odkazy směřující na starou doménu.
|
||||||
6
frontend/src/locale/src/HelpDoc/cs/Streams.md
Normal file
6
frontend/src/locale/src/HelpDoc/cs/Streams.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
## Co je stream?
|
||||||
|
|
||||||
|
Stream je relativně nová funkce pro Nginx, která slouží na přesměrování TCP/UDP
|
||||||
|
datového toku přímo do jiného počítače v síti.
|
||||||
|
|
||||||
|
Pokud provozujete herní servery, FTP nebo SSH servery, tato funkce se vám může hodit.
|
||||||
6
frontend/src/locale/src/HelpDoc/cs/index.ts
Normal file
6
frontend/src/locale/src/HelpDoc/cs/index.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export * as AccessLists from "./AccessLists.md";
|
||||||
|
export * as Certificates from "./Certificates.md";
|
||||||
|
export * as DeadHosts from "./DeadHosts.md";
|
||||||
|
export * as ProxyHosts from "./ProxyHosts.md";
|
||||||
|
export * as RedirectionHosts from "./RedirectionHosts.md";
|
||||||
|
export * as Streams from "./Streams.md";
|
||||||
7
frontend/src/locale/src/HelpDoc/et/AccessLists.md
Normal file
7
frontend/src/locale/src/HelpDoc/et/AccessLists.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## Mis on juurdepääsuloend?
|
||||||
|
|
||||||
|
Ligipääsuloendid pakuvad konkreetsete klientide IP-aadresside musta või valget nimekirja koos puhverserverite autentimisega põhilise HTTP-autentimise kaudu.
|
||||||
|
|
||||||
|
Saate ühe juurdepääsuloendi jaoks konfigureerida mitu kliendireeglit, kasutajanime ja parooli ning seejärel rakendada neid ühele või mitmele _puhverserverile_.
|
||||||
|
|
||||||
|
See on kõige kasulikum edastatud veebiteenuste puhul, millel pole sisseehitatud autentimismehhanisme või kui soovite kaitsta tundmatute klientide eest.
|
||||||
26
frontend/src/locale/src/HelpDoc/et/Certificates.md
Normal file
26
frontend/src/locale/src/HelpDoc/et/Certificates.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
## Sertifikaatide abi
|
||||||
|
|
||||||
|
### HTTP-sertifikaat
|
||||||
|
|
||||||
|
HTTP-valideeritud sertifikaat tähendab, et Let's Encrypti serverid
|
||||||
|
|
||||||
|
proovivad teie domeenidega ühendust luua HTTP (mitte HTTPS!) kaudu ja kui see õnnestub,
|
||||||
|
väljastavad nad teile sertifikaadi.
|
||||||
|
|
||||||
|
Selle meetodi jaoks peate oma domeeni(de) jaoks looma _Proxy Host_, millele pääseb ligi HTTP kaudu ja mis osutab sellele Nginxi installile. Pärast sertifikaadi väljastamist saate muuta _Proxy Host_'i, et seda sertifikaati ka HTTPS
|
||||||
|
ühenduste jaoks kasutada. Sertifikaadi uuendamiseks tuleb aga _Proxy Host_ ikkagi HTTP-juurdepääsu jaoks konfigureerida.
|
||||||
|
|
||||||
|
See protsess _ei_ toeta metamärke kasutavaid domeene.
|
||||||
|
|
||||||
|
### DNS-sertifikaat
|
||||||
|
|
||||||
|
DNS-i poolt valideeritud sertifikaadi saamiseks peate kasutama DNS-pakkuja pistikprogrammi. Seda DNS-teenuse pakkujat kasutatakse teie domeenis ajutiste kirjete loomiseks ja seejärel pärib Let's
|
||||||
|
Encrypt nende kirjete kohta päringu, et veenduda, et olete omanik, ja kui see õnnestub, väljastavad nad teile sertifikaadi.
|
||||||
|
|
||||||
|
Selle tüüpi sertifikaadi taotlemiseks ei ole vaja luua _Proxy Host_'i. Samuti ei pea teie _Proxy Host_ olema HTTP-juurdepääsu jaoks konfigureeritud.
|
||||||
|
|
||||||
|
See protsess _toetab_ metamärke kasutavaid domeene.
|
||||||
|
|
||||||
|
### Kohandatud sertifikaat
|
||||||
|
|
||||||
|
Kasutage seda valikut oma SSL-sertifikaadi üleslaadimiseks, mille on esitanud teie enda sertifitseerimisasutus.
|
||||||
9
frontend/src/locale/src/HelpDoc/et/DeadHosts.md
Normal file
9
frontend/src/locale/src/HelpDoc/et/DeadHosts.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
## Mis on 404 host?
|
||||||
|
|
||||||
|
404 host on lihtsalt hosti seadistus, mis kuvab 404 lehte.
|
||||||
|
|
||||||
|
See võib olla kasulik, kui teie domeen on otsingumootorites loetletud ja soovite
|
||||||
|
esitada kenama vealehe või konkreetselt otsingu indekseerijatele öelda, et
|
||||||
|
domeenilehed enam ei eksisteeri.
|
||||||
|
|
||||||
|
Selle hosti teine eelis on selle külastatavuste logide jälgimine ja suunajate vaatamine.
|
||||||
7
frontend/src/locale/src/HelpDoc/et/ProxyHosts.md
Normal file
7
frontend/src/locale/src/HelpDoc/et/ProxyHosts.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## Mis on puhverserver?
|
||||||
|
|
||||||
|
Puhverserver on veebiteenuse sissetuleva andmevoo lõpp-punkt, mida soovite edastada.
|
||||||
|
|
||||||
|
See pakub valikulist SSL-i lõpetamist teie teenusele, millel ei pruugi olla sisseehitatud SSL-tuge.
|
||||||
|
|
||||||
|
Puhverserverid on Nginxi puhverserveri halduri kõige levinum kasutusala.
|
||||||
5
frontend/src/locale/src/HelpDoc/et/RedirectionHosts.md
Normal file
5
frontend/src/locale/src/HelpDoc/et/RedirectionHosts.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
## Mis on ümbersuunamishost?
|
||||||
|
|
||||||
|
Ümbersuunamishost suunab sissetuleva domeeni päringud ümber ja suunab vaataja teisele domeenile.
|
||||||
|
|
||||||
|
Kõige levinum põhjus seda tüüpi hosti kasutamiseks on see, kui teie veebisaidi domeenid muutuvad, kuid otsingumootori või suunaja lingid osutavad endiselt vanale domeenile.
|
||||||
5
frontend/src/locale/src/HelpDoc/et/Streams.md
Normal file
5
frontend/src/locale/src/HelpDoc/et/Streams.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
## Mis on voog?
|
||||||
|
|
||||||
|
Nginxi suhteliselt uus funktsioon, voog, edastab TCP/UDP liiklust otse võrgus olevale teisele arvutile.
|
||||||
|
|
||||||
|
Kui sul on mänguserverid, FTP- või SSH-serverid, võib see kasuks tulla.
|
||||||
6
frontend/src/locale/src/HelpDoc/et/index.ts
Normal file
6
frontend/src/locale/src/HelpDoc/et/index.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export * as AccessLists from "./AccessLists.md";
|
||||||
|
export * as Certificates from "./Certificates.md";
|
||||||
|
export * as DeadHosts from "./DeadHosts.md";
|
||||||
|
export * as ProxyHosts from "./ProxyHosts.md";
|
||||||
|
export * as RedirectionHosts from "./RedirectionHosts.md";
|
||||||
|
export * as Streams from "./Streams.md";
|
||||||
7
frontend/src/locale/src/HelpDoc/fr/AccessLists.md
Normal file
7
frontend/src/locale/src/HelpDoc/fr/AccessLists.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## Qu'est-ce qu'une liste d'accès ?
|
||||||
|
|
||||||
|
Les listes d'accès permettent de définir une liste noire ou une liste blanche d'adresses IP clientes spécifiques, ainsi que l'authentification des Hôtes Proxy via l'authentification HTTP de base.
|
||||||
|
|
||||||
|
Vous pouvez configurer plusieurs règles client, noms d'utilisateur et mots de passe pour une même liste d'accès, puis l'appliquer à un ou plusieurs Hôtes Proxy.
|
||||||
|
|
||||||
|
Ceci est particulièrement utile pour les services web redirigés qui ne disposent pas de mécanismes d'authentification intégrés ou lorsque vous souhaitez vous protéger contre les clients inconnus.
|
||||||
23
frontend/src/locale/src/HelpDoc/fr/Certificates.md
Normal file
23
frontend/src/locale/src/HelpDoc/fr/Certificates.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
## Aide concernant les certificats
|
||||||
|
|
||||||
|
### Certificat HTTP
|
||||||
|
|
||||||
|
Un certificat HTTP validé signifie que les serveurs de Let's Encrypt testeront d'accéder à vos domaines via HTTP (et non HTTPS !). En cas de succès, ils émettront votre certificat.
|
||||||
|
|
||||||
|
Pour cette méthode, vous devrez créer un Hôte Proxy pour votre ou vos domaines. Cet Hôte Proxy devra être accessible via HTTP et pointer vers cette installation Nginx. Une fois le certificat émis, vous pourrez modifier l'Hôte Proxy pour qu'il utilise également ce certificat pour les connexions HTTPS. Cependant, l'Hôte Proxy devra toujours être configuré pour l'accès HTTP afin que le certificat puisse être renouvelé.
|
||||||
|
|
||||||
|
Ce processus ne prend pas en charge les domaines génériques.
|
||||||
|
|
||||||
|
### Certificat DNS
|
||||||
|
|
||||||
|
Un certificat DNS validé nécessite l'utilisation du plugin Fournisseur DNS. Fournisseur DNS créera des enregistrements temporaires sur votre domaine. Let's Encrypt interrogera ensuite ces enregistrements pour vérifier que vous en êtes bien le propriétaire. En cas de succès, votre certificat sera émis.
|
||||||
|
|
||||||
|
Il n'est pas nécessaire de créer un Hôte Proxy avant de demander ce type de certificat.
|
||||||
|
|
||||||
|
Il n'est pas non plus nécessaire de configurer votre Hôte Proxy pour l'accès HTTP.
|
||||||
|
|
||||||
|
Ce processus prend en charge les domaines génériques.
|
||||||
|
|
||||||
|
## Certificat personnalisé
|
||||||
|
|
||||||
|
Utilisez cette option pour importer votre propre certificat SSL, fourni par votre autorité de certification.
|
||||||
7
frontend/src/locale/src/HelpDoc/fr/DeadHosts.md
Normal file
7
frontend/src/locale/src/HelpDoc/fr/DeadHosts.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## Qu'est-ce qu'un serveur 404 ?
|
||||||
|
|
||||||
|
Un Hôte 404 est simplement un hôte configuré pour afficher une page 404.
|
||||||
|
|
||||||
|
Cela peut s'avérer utile lorsque votre domaine est indexé par les moteurs de recherche et que vous souhaitez fournir une page d'erreur plus conviviale ou, plus précisément, indiquer aux moteurs de recherche que les pages du domaine n'existent plus.
|
||||||
|
|
||||||
|
Un autre avantage de cet hôte est la possibilité de suivre les journaux et de consulter les sites référenceurs.
|
||||||
7
frontend/src/locale/src/HelpDoc/fr/ProxyHosts.md
Normal file
7
frontend/src/locale/src/HelpDoc/fr/ProxyHosts.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## Qu'est-ce qu'un hôte proxy ?
|
||||||
|
|
||||||
|
Un Hôte Proxy est le point de terminaison entrant d'un service web que vous souhaitez rediriger.
|
||||||
|
|
||||||
|
Il assure la terminaison SSL optionnelle pour votre service qui ne prend pas en charge SSL nativement.
|
||||||
|
|
||||||
|
Les Hôtes Proxy constituent l'utilisation la plus courante du Nginx Proxy Manager.
|
||||||
5
frontend/src/locale/src/HelpDoc/fr/RedirectionHosts.md
Normal file
5
frontend/src/locale/src/HelpDoc/fr/RedirectionHosts.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
## Qu'est-ce qu'un serveur de redirection ?
|
||||||
|
|
||||||
|
Un Hôte de Redirection redirige les requêtes provenant du domaine entrant vers un autre domaine.
|
||||||
|
|
||||||
|
On utilise généralement ce type d'hôte lorsque votre site web change de domaine, mais que des liens provenant des moteurs de recherche ou des sites référenceurs pointent toujours vers l'ancien domaine.
|
||||||
5
frontend/src/locale/src/HelpDoc/fr/Streams.md
Normal file
5
frontend/src/locale/src/HelpDoc/fr/Streams.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
## Qu'est-ce qu'un Stream ?
|
||||||
|
|
||||||
|
Fonctionnalité relativement récente de Nginx, un Stream permet de rediriger le trafic TCP/UDP directement vers un autre ordinateur du réseau.
|
||||||
|
|
||||||
|
Si vous gérez des serveurs de jeux, FTP ou SSH, cela peut s'avérer très utile.
|
||||||
6
frontend/src/locale/src/HelpDoc/fr/index.ts
Normal file
6
frontend/src/locale/src/HelpDoc/fr/index.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export * as AccessLists from "./AccessLists.md";
|
||||||
|
export * as Certificates from "./Certificates.md";
|
||||||
|
export * as DeadHosts from "./DeadHosts.md";
|
||||||
|
export * as ProxyHosts from "./ProxyHosts.md";
|
||||||
|
export * as RedirectionHosts from "./RedirectionHosts.md";
|
||||||
|
export * as Streams from "./Streams.md";
|
||||||
7
frontend/src/locale/src/HelpDoc/hu/AccessLists.md
Normal file
7
frontend/src/locale/src/HelpDoc/hu/AccessLists.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## Mi az a hozzáférési lista?
|
||||||
|
|
||||||
|
A hozzáférési listák feketelistát vagy fehérlistát biztosítanak meghatározott kliens IP-címekhez, valamint alap HTTP-hitelesítést (Basic HTTP Authentication) a proxy kiszolgálókhoz.
|
||||||
|
|
||||||
|
Egyetlen hozzáférési listához több kliensszabályt, felhasználónevet és jelszót is beállíthatsz, majd ezt alkalmazhatod egy vagy több _Proxy Kiszolgáló_-ra.
|
||||||
|
|
||||||
|
Ez különösen hasznos olyan továbbított webszolgáltatásoknál, amelyekben nincs beépített hitelesítési mechanizmus, vagy amikor ismeretlen kliensektől szeretnél védeni.
|
||||||
21
frontend/src/locale/src/HelpDoc/hu/Certificates.md
Normal file
21
frontend/src/locale/src/HelpDoc/hu/Certificates.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
## Tanúsítványok súgó
|
||||||
|
|
||||||
|
### HTTP tanúsítvány
|
||||||
|
|
||||||
|
A HTTP érvényes tanúsítvány azt jelenti, hogy a Let's Encrypt szerverek megpróbálják elérni a domaineket HTTP-n keresztül (nem HTTPS-en!), és ha sikerül, kiállítják a tanúsítványt.
|
||||||
|
|
||||||
|
Ehhez a módszerhez létre kell hoznod egy _Proxy Kiszolgáló_-t a domain(ek)hez, amely HTTP-n keresztül elérhető és erre az Nginx telepítésre mutat. Miután a tanúsítvány megérkezett, módosíthatod a _Proxy Kiszolgáló_-t, hogy ezt a tanúsítványt használja a HTTPS kapcsolatokhoz is. Azonban a _Proxy Kiszolgáló_-nak továbbra is konfigurálva kell lennie HTTP hozzáféréshez, hogy a tanúsítvány megújulhasson.
|
||||||
|
|
||||||
|
Ez a folyamat _nem_ támogatja a helyettesítő karakteres domaineket.
|
||||||
|
|
||||||
|
### DNS tanúsítvány
|
||||||
|
|
||||||
|
A DNS érvényes tanúsítvány megköveteli, hogy DNS szolgáltató plugint használj. Ez a DNS szolgáltató ideiglenes rekordokat hoz létre a domainen, majd a Let's Encrypt lekérdezi ezeket a rekordokat, hogy megbizonyosodjon a tulajdonjogról, és ha sikeres, kiállítják a tanúsítványt.
|
||||||
|
|
||||||
|
Nem szükséges előzetesen _Proxy Kiszolgáló_-t létrehozni az ilyen típusú tanúsítvány igényléséhez. Nem is kell a _Proxy Kiszolgáló_-t HTTP hozzáférésre konfigurálni.
|
||||||
|
|
||||||
|
Ez a folyamat _támogatja_ a helyettesítő karakteres domaineket.
|
||||||
|
|
||||||
|
### Egyéni tanúsítvány
|
||||||
|
|
||||||
|
Ezt az opciót használd a saját SSL tanúsítvány feltöltéséhez, amelyet a saját tanúsítványkibocsátód biztosított.
|
||||||
7
frontend/src/locale/src/HelpDoc/hu/DeadHosts.md
Normal file
7
frontend/src/locale/src/HelpDoc/hu/DeadHosts.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## Mi az a 404-es Kiszolgáló?
|
||||||
|
|
||||||
|
A 404-es Kiszolgáló egyszerűen egy olyan kiszolgáló beállítás, amely egy 404-es oldalt jelenít meg.
|
||||||
|
|
||||||
|
Ez akkor lehet hasznos, ha a domained szerepel a keresőmotorokban, és egy szebb hibaoldalt szeretnél nyújtani, vagy kifejezetten jelezni akarod a keresőrobotoknak, hogy a domain oldalai már nem léteznek.
|
||||||
|
|
||||||
|
Ennek a kiszolgálónak egy további előnye, hogy nyomon követheted a rá érkező találatokat a naplókban, és megtekintheted a hivatkozó oldalakat.
|
||||||
7
frontend/src/locale/src/HelpDoc/hu/ProxyHosts.md
Normal file
7
frontend/src/locale/src/HelpDoc/hu/ProxyHosts.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## Mi az a Proxy Kiszolgáló?
|
||||||
|
|
||||||
|
A Proxy Kiszolgáló egy bejövő végpont egy olyan webszolgáltatáshoz, amelyet továbbítani szeretnél.
|
||||||
|
|
||||||
|
Opcionális SSL lezárást biztosít a szolgáltatásodhoz, amelyben esetleg nincs beépített SSL támogatás.
|
||||||
|
|
||||||
|
A Proxy Kiszolgálók az Nginx Proxy Manager leggyakoribb felhasználási módjai.
|
||||||
5
frontend/src/locale/src/HelpDoc/hu/RedirectionHosts.md
Normal file
5
frontend/src/locale/src/HelpDoc/hu/RedirectionHosts.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
## Mi az az Átirányító Kiszolgáló?
|
||||||
|
|
||||||
|
Az Átirányító Kiszolgáló a bejövő domainre érkező kéréseket átirányítja, és a látogatót egy másik domainre küldi.
|
||||||
|
|
||||||
|
Ennek a kiszolgálótípusnak a leggyakoribb használati oka az, amikor a weboldalad domaint vált, de a keresőkben vagy a hivatkozó oldalakon még mindig a régi domainre mutató linkek vannak.
|
||||||
5
frontend/src/locale/src/HelpDoc/hu/Streams.md
Normal file
5
frontend/src/locale/src/HelpDoc/hu/Streams.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
## Mi az a Stream?
|
||||||
|
|
||||||
|
Az Nginx egy viszonylag új funkciója, a Stream arra szolgál, hogy a TCP/UDP forgalmat közvetlenül továbbítsa a hálózat egy másik számítógépére.
|
||||||
|
|
||||||
|
Ha játékszervereket, FTP vagy SSH szervereket futtatsz, ez hasznos lehet.
|
||||||
6
frontend/src/locale/src/HelpDoc/hu/index.ts
Normal file
6
frontend/src/locale/src/HelpDoc/hu/index.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export * as AccessLists from "./AccessLists.md";
|
||||||
|
export * as Certificates from "./Certificates.md";
|
||||||
|
export * as DeadHosts from "./DeadHosts.md";
|
||||||
|
export * as ProxyHosts from "./ProxyHosts.md";
|
||||||
|
export * as RedirectionHosts from "./RedirectionHosts.md";
|
||||||
|
export * as Streams from "./Streams.md";
|
||||||
@@ -1,34 +1,36 @@
|
|||||||
|
import * as bg from "./bg/index";
|
||||||
import * as de from "./de/index";
|
import * as de from "./de/index";
|
||||||
|
import * as pt from "./pt/index";
|
||||||
import * as en from "./en/index";
|
import * as en from "./en/index";
|
||||||
import * as ga from './ga/index'
|
import * as es from "./es/index";
|
||||||
|
import * as et from "./et/index";
|
||||||
|
import * as fr from "./fr/index";
|
||||||
|
import * as ga from "./ga/index";
|
||||||
import * as id from "./id/index";
|
import * as id from "./id/index";
|
||||||
import * as it from "./it/index";
|
import * as it from "./it/index";
|
||||||
import * as ja from "./ja/index";
|
import * as ja from "./ja/index";
|
||||||
|
import * as ko from "./ko/index";
|
||||||
import * as nl from "./nl/index";
|
import * as nl from "./nl/index";
|
||||||
import * as pl from "./pl/index";
|
import * as pl from "./pl/index";
|
||||||
import * as ru from "./ru/index";
|
import * as ru from "./ru/index";
|
||||||
import * as sk from "./sk/index";
|
import * as sk from "./sk/index";
|
||||||
|
import * as cs from "./cs/index";
|
||||||
import * as vi from "./vi/index";
|
import * as vi from "./vi/index";
|
||||||
import * as zh from "./zh/index";
|
import * as zh from "./zh/index";
|
||||||
import * as ko from "./ko/index";
|
import * as tr from "./tr/index";
|
||||||
import * as bg from "./bg/index";
|
import * as hu from "./hu/index";
|
||||||
|
|
||||||
|
const items: any = { en, de, pt, es, et, ja, sk, cs, zh, pl, ru, it, vi, nl, bg, ko, ga, id, fr, tr, hu };
|
||||||
|
|
||||||
const items: any = { en, de, ja, sk, zh, pl, ru, it, vi, nl, bg, ko, ga, id }
|
|
||||||
|
|
||||||
const fallbackLang = "en";
|
const fallbackLang = "en";
|
||||||
|
|
||||||
export const getHelpFile = (lang: string, section: string): string => {
|
export const getHelpFile = (lang: string, section: string): string => {
|
||||||
if (
|
if (typeof items[lang] !== "undefined" && typeof items[lang][section] !== "undefined") {
|
||||||
typeof items[lang] !== "undefined" &&
|
|
||||||
typeof items[lang][section] !== "undefined"
|
|
||||||
) {
|
|
||||||
return items[lang][section].default;
|
return items[lang][section].default;
|
||||||
}
|
}
|
||||||
// Fallback to English
|
// Fallback to English
|
||||||
if (
|
if (typeof items[fallbackLang] !== "undefined" && typeof items[fallbackLang][section] !== "undefined") {
|
||||||
typeof items[fallbackLang] !== "undefined" &&
|
|
||||||
typeof items[fallbackLang][section] !== "undefined"
|
|
||||||
) {
|
|
||||||
return items[fallbackLang][section].default;
|
return items[fallbackLang][section].default;
|
||||||
}
|
}
|
||||||
throw new Error(`Cannot load help doc for ${lang}-${section}`);
|
throw new Error(`Cannot load help doc for ${lang}-${section}`);
|
||||||
|
|||||||
7
frontend/src/locale/src/HelpDoc/no/AccessLists.md
Normal file
7
frontend/src/locale/src/HelpDoc/no/AccessLists.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## Hva er en tilgangsliste?
|
||||||
|
|
||||||
|
Tilgangslister gir en svarteliste eller hviteliste over spesifikke klient‑IP‑adresser, sammen med autentisering for `Proxy‑hosts` via Basic HTTP‑autentisering.
|
||||||
|
|
||||||
|
Du kan konfigurere flere klientregler, brukernavn og passord for én tilgangsliste og deretter bruke denne på én eller flere `Proxy‑hosts`.
|
||||||
|
|
||||||
|
Dette er spesielt nyttig for videresendte webtjenester som ikke har innebygd autentisering, eller når du ønsker å beskytte mot ukjente klienter.
|
||||||
29
frontend/src/locale/src/HelpDoc/no/Certificates.md
Normal file
29
frontend/src/locale/src/HelpDoc/no/Certificates.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
## Hjelp om sertifikater
|
||||||
|
|
||||||
|
### HTTP‑sertifikat
|
||||||
|
|
||||||
|
Et HTTP‑validert sertifikat betyr at Let's Encrypt‑serverne vil forsøke å nå
|
||||||
|
domenene dine over HTTP (ikke HTTPS!) og hvis det lykkes, vil de utstede sertifikatet.
|
||||||
|
|
||||||
|
For denne metoden må du ha en `Proxy‑host` opprettet for domenet/domenene dine som
|
||||||
|
er tilgjengelig over HTTP og peker til denne Nginx‑installasjonen. Etter at et sertifikat
|
||||||
|
er utstedt, kan du endre `Proxy‑host` til også å bruke dette sertifikatet for HTTPS‑tilkoblinger.
|
||||||
|
Proxy‑hosten må imidlertid fortsatt være konfigurert for HTTP‑tilgang for at sertifikatet skal kunne fornyes.
|
||||||
|
|
||||||
|
Denne prosessen _støtter ikke_ wildcard‑domener.
|
||||||
|
|
||||||
|
### DNS‑sertifikat
|
||||||
|
|
||||||
|
Et DNS‑validert sertifikat krever at du bruker en DNS‑leverandør‑plugin. Denne leverandøren
|
||||||
|
vil opprette midlertidige DNS‑poster på domenet ditt, og Let's Encrypt vil deretter spørre
|
||||||
|
disse postene for å bekrefte at du eier domenet. Hvis valideringen lykkes, utstedes sertifikatet.
|
||||||
|
|
||||||
|
Du trenger ikke å ha en `Proxy‑host` opprettet før du ber om denne typen sertifikat. Du trenger heller
|
||||||
|
ikke at `Proxy‑host` er konfigurert for HTTP‑tilgang.
|
||||||
|
|
||||||
|
Denne prosessen _støtter_ wildcard‑domener.
|
||||||
|
|
||||||
|
### Egendefinert sertifikat
|
||||||
|
|
||||||
|
Bruk dette alternativet for å laste opp ditt eget SSL‑sertifikat, levert av din
|
||||||
|
egen sertifikatmyndighet (CA).
|
||||||
10
frontend/src/locale/src/HelpDoc/no/DeadHosts.md
Normal file
10
frontend/src/locale/src/HelpDoc/no/DeadHosts.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
## Hva er en 404‑host?
|
||||||
|
|
||||||
|
En 404‑host er enkelt og greit en host‑oppsett som viser en 404‑side.
|
||||||
|
|
||||||
|
Dette kan være nyttig når domenet ditt er oppført i søkemotorer og du ønsker å
|
||||||
|
vise en penere feilmelding, eller for å fortelle søkeindekser at sidene på domenet
|
||||||
|
ikke lenger eksisterer.
|
||||||
|
|
||||||
|
En annen fordel med å ha denne hosten er å kunne spore treff i loggene og
|
||||||
|
se hvilke henvisere som kommer til den.
|
||||||
7
frontend/src/locale/src/HelpDoc/no/ProxyHosts.md
Normal file
7
frontend/src/locale/src/HelpDoc/no/ProxyHosts.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## Hva er en Proxy‑host?
|
||||||
|
|
||||||
|
En Proxy‑host er inngangspunktet (innkommende endepunkt) for en webtjeneste du ønsker å videresende.
|
||||||
|
|
||||||
|
Den tilbyr valgfri SSL‑terminering for tjenesten din hvis tjenesten ikke har innebygd støtte for SSL.
|
||||||
|
|
||||||
|
Proxy‑hosts er den vanligste bruken av Nginx Proxy Manager.
|
||||||
7
frontend/src/locale/src/HelpDoc/no/RedirectionHosts.md
Normal file
7
frontend/src/locale/src/HelpDoc/no/RedirectionHosts.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## Hva er en omdirigerings‑host?
|
||||||
|
|
||||||
|
En omdirigerings‑host omdirigerer forespørsler fra det innkommende domenet og videresender
|
||||||
|
brukeren til et annet domene.
|
||||||
|
|
||||||
|
Den vanligste årsaken til å bruke denne typen host er når nettstedet ditt har byttet
|
||||||
|
domene, men søkemotorer eller henvisningslenker fortsatt peker til det gamle domenet.
|
||||||
6
frontend/src/locale/src/HelpDoc/no/Streams.md
Normal file
6
frontend/src/locale/src/HelpDoc/no/Streams.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
## Hva er en Stream?
|
||||||
|
|
||||||
|
En relativt ny funksjon i Nginx. En Stream brukes til å videresende TCP/UDP‑trafikk
|
||||||
|
direkte til en annen maskin i nettverket.
|
||||||
|
|
||||||
|
Dette er nyttig hvis du kjører spillservere, FTP‑ eller SSH‑servere.
|
||||||
6
frontend/src/locale/src/HelpDoc/no/index.ts
Normal file
6
frontend/src/locale/src/HelpDoc/no/index.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export * as AccessLists from "./AccessLists.md";
|
||||||
|
export * as Certificates from "./Certificates.md";
|
||||||
|
export * as DeadHosts from "./DeadHosts.md";
|
||||||
|
export * as ProxyHosts from "./ProxyHosts.md";
|
||||||
|
export * as RedirectionHosts from "./RedirectionHosts.md";
|
||||||
|
export * as Streams from "./Streams.md";
|
||||||
11
frontend/src/locale/src/HelpDoc/pt/AccessLists.md
Normal file
11
frontend/src/locale/src/HelpDoc/pt/AccessLists.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
## O que é uma Access List?
|
||||||
|
|
||||||
|
As *Access Lists* fornecem uma lista de permissões (whitelist) ou bloqueios (blacklist)
|
||||||
|
de endereços IP específicos de clientes, juntamente com autenticação para os *Proxy Hosts*
|
||||||
|
via Autenticação HTTP Básica (*Basic Auth*).
|
||||||
|
|
||||||
|
Podes configurar múltiplas regras de cliente, nomes de utilizador e palavras-passe
|
||||||
|
para uma única *Access List*, e depois aplicá-la a um ou mais *Proxy Hosts*.
|
||||||
|
|
||||||
|
Isto é especialmente útil para serviços web encaminhados que não têm mecanismos
|
||||||
|
de autenticação integrados ou quando pretendes proteger o acesso contra clientes desconhecidos.
|
||||||
31
frontend/src/locale/src/HelpDoc/pt/Certificates.md
Normal file
31
frontend/src/locale/src/HelpDoc/pt/Certificates.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
## Ajuda de Certificados
|
||||||
|
|
||||||
|
### Certificado HTTP
|
||||||
|
|
||||||
|
Um certificado validado por HTTP significa que os servidores do Let's Encrypt irão
|
||||||
|
tentar aceder aos teus domínios via HTTP (não HTTPS!) e, se a ligação for bem-sucedida,
|
||||||
|
emitirão o certificado.
|
||||||
|
|
||||||
|
Para este método, é necessário ter um *Proxy Host* criado para o(s) teu(s) domínio(s),
|
||||||
|
acessível via HTTP e a apontar para esta instalação do Nginx. Depois de o certificado ser
|
||||||
|
emitido, podes modificar o *Proxy Host* para também utilizar esse certificado em ligações HTTPS.
|
||||||
|
No entanto, o *Proxy Host* deve continuar configurado para acesso HTTP para que a renovação
|
||||||
|
funcione corretamente.
|
||||||
|
|
||||||
|
Este processo **não** suporta domínios wildcard.
|
||||||
|
|
||||||
|
### Certificado DNS
|
||||||
|
|
||||||
|
Um certificado validado por DNS requer que uses um plugin de fornecedor DNS (*DNS Provider*).
|
||||||
|
Este fornecedor será usado para criar registos temporários no teu domínio, que serão consultados
|
||||||
|
pelo Let's Encrypt para confirmar que és o proprietário. Se tudo correr bem, o certificado será emitido.
|
||||||
|
|
||||||
|
Não é necessário ter um *Proxy Host* criado antes de pedir este tipo de certificado.
|
||||||
|
Também não é necessário que o *Proxy Host* tenha acesso HTTP configurado.
|
||||||
|
|
||||||
|
Este processo **suporta** domínios wildcard.
|
||||||
|
|
||||||
|
### Certificado Personalizado
|
||||||
|
|
||||||
|
Usa esta opção para carregar o teu próprio Certificado SSL, fornecido pela
|
||||||
|
tua Autoridade Certificadora.
|
||||||
9
frontend/src/locale/src/HelpDoc/pt/DeadHosts.md
Normal file
9
frontend/src/locale/src/HelpDoc/pt/DeadHosts.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
## O que é um 404 Host?
|
||||||
|
|
||||||
|
Um *404 Host* é simplesmente um host configurado para apresentar uma página 404.
|
||||||
|
|
||||||
|
Isto pode ser útil quando o teu domínio aparece em motores de busca e queres fornecer
|
||||||
|
uma página de erro mais agradável ou indicar especificamente aos indexadores de pesquisa
|
||||||
|
que as páginas desse domínio já não existem.
|
||||||
|
|
||||||
|
Outra vantagem é permitir consultar os registos de acessos a este host e ver os referenciadores.
|
||||||
7
frontend/src/locale/src/HelpDoc/pt/ProxyHosts.md
Normal file
7
frontend/src/locale/src/HelpDoc/pt/ProxyHosts.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## O que é um Proxy Host?
|
||||||
|
|
||||||
|
Um *Proxy Host* é o ponto de entrada para um serviço web que pretendes encaminhar.
|
||||||
|
|
||||||
|
Permite, opcionalmente, fazer terminação SSL para um serviço que possa não ter suporte SSL nativo.
|
||||||
|
|
||||||
|
Os *Proxy Hosts* são a utilização mais comum do Nginx Proxy Manager.
|
||||||
7
frontend/src/locale/src/HelpDoc/pt/RedirectionHosts.md
Normal file
7
frontend/src/locale/src/HelpDoc/pt/RedirectionHosts.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## O que é um Redirection Host?
|
||||||
|
|
||||||
|
Um *Redirection Host* redireciona pedidos recebidos no domínio de entrada e envia
|
||||||
|
o utilizador para outro domínio.
|
||||||
|
|
||||||
|
A razão mais comum para usar este tipo de host é quando o teu site muda de domínio
|
||||||
|
mas ainda tens motores de busca ou links de referência a apontar para o domínio antigo.
|
||||||
6
frontend/src/locale/src/HelpDoc/pt/Streams.md
Normal file
6
frontend/src/locale/src/HelpDoc/pt/Streams.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
## O que é um Stream?
|
||||||
|
|
||||||
|
Uma funcionalidade relativamente recente no Nginx, um *Stream* serve para encaminhar
|
||||||
|
tráfego TCP/UDP diretamente para outro computador na rede.
|
||||||
|
|
||||||
|
Se estiveres a executar servidores de jogos, FTP ou SSH, isto pode ser bastante útil.
|
||||||
6
frontend/src/locale/src/HelpDoc/pt/index.ts
Normal file
6
frontend/src/locale/src/HelpDoc/pt/index.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export * as AccessLists from "./AccessLists.md";
|
||||||
|
export * as Certificates from "./Certificates.md";
|
||||||
|
export * as DeadHosts from "./DeadHosts.md";
|
||||||
|
export * as ProxyHosts from "./ProxyHosts.md";
|
||||||
|
export * as RedirectionHosts from "./RedirectionHosts.md";
|
||||||
|
export * as Streams from "./Streams.md";
|
||||||
8
frontend/src/locale/src/HelpDoc/tr/AccessLists.md
Normal file
8
frontend/src/locale/src/HelpDoc/tr/AccessLists.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
## Erişim Listesi Nedir?
|
||||||
|
|
||||||
|
Erişim Listeleri, Temel HTTP Kimlik Doğrulama aracılığıyla Proxy Host'lar için belirli istemci IP adreslerinin kara listesi veya beyaz listesini ve kimlik doğrulamasını sağlar.
|
||||||
|
|
||||||
|
Tek bir Erişim Listesi için birden fazla istemci kuralı, kullanıcı adı ve şifre yapılandırabilir ve bunu bir veya daha fazla _Proxy Host_'a uygulayabilirsiniz.
|
||||||
|
|
||||||
|
Bu, yerleşik kimlik doğrulama mekanizmaları olmayan veya bilinmeyen istemcilerden korunmak istediğinizde iletilen web hizmetleri için en kullanışlıdır.
|
||||||
|
|
||||||
29
frontend/src/locale/src/HelpDoc/tr/Certificates.md
Normal file
29
frontend/src/locale/src/HelpDoc/tr/Certificates.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
## Sertifika Yardımı
|
||||||
|
|
||||||
|
### HTTP Sertifikası
|
||||||
|
|
||||||
|
Bir HTTP doğrulanmış sertifika, Let's Encrypt sunucularının
|
||||||
|
alan adlarınıza HTTP (HTTPS değil!) üzerinden ulaşmaya çalışacağı ve başarılı olursa,
|
||||||
|
sertifikanızı verecekleri anlamına gelir.
|
||||||
|
|
||||||
|
Bu yöntem için, alan adlarınız için HTTP ile erişilebilir ve bu Nginx kurulumuna işaret eden bir _Proxy Host_ oluşturulmuş olmalıdır. Bir sertifika
|
||||||
|
verildikten sonra, _Proxy Host_'u HTTPS
|
||||||
|
bağlantıları için de bu sertifikayı kullanacak şekilde değiştirebilirsiniz. Ancak, sertifikanın yenilenmesi için _Proxy Host_'un hala HTTP erişimi için yapılandırılmış olması gerekecektir.
|
||||||
|
|
||||||
|
Bu işlem joker karakter alan adlarını _desteklemez_.
|
||||||
|
|
||||||
|
### DNS Sertifikası
|
||||||
|
|
||||||
|
Bir DNS doğrulanmış sertifika, bir DNS Sağlayıcı eklentisi kullanmanızı gerektirir. Bu DNS
|
||||||
|
Sağlayıcı, alan adınızda geçici kayıtlar oluşturmak için kullanılacak ve ardından Let's
|
||||||
|
Encrypt bu kayıtları sorgulayarak sahibi olduğunuzdan emin olacak ve başarılı olursa,
|
||||||
|
sertifikanızı verecektir.
|
||||||
|
|
||||||
|
Bu tür bir sertifika talep etmeden önce bir _Proxy Host_ oluşturulmasına gerek yoktur. Ayrıca _Proxy Host_'unuzun HTTP erişimi için yapılandırılmasına da gerek yoktur.
|
||||||
|
|
||||||
|
Bu işlem joker karakter alan adlarını _destekler_.
|
||||||
|
|
||||||
|
### Özel Sertifika
|
||||||
|
|
||||||
|
Kendi Sertifika Otoriteniz tarafından sağlanan kendi SSL Sertifikanızı yüklemek için bu seçeneği kullanın.
|
||||||
|
|
||||||
10
frontend/src/locale/src/HelpDoc/tr/DeadHosts.md
Normal file
10
frontend/src/locale/src/HelpDoc/tr/DeadHosts.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
## 404 Host Nedir?
|
||||||
|
|
||||||
|
404 Host, basitçe bir 404 sayfası gösteren bir host kurulumudur.
|
||||||
|
|
||||||
|
Bu, alan adınız arama motorlarında listelendiğinde ve daha güzel bir hata sayfası sağlamak veya özellikle arama dizinleyicilerine
|
||||||
|
alan adı sayfalarının artık mevcut olmadığını söylemek istediğinizde yararlı olabilir.
|
||||||
|
|
||||||
|
Bu host'un bir başka faydası da, ona yapılan isteklerin loglarını takip etmek ve
|
||||||
|
referansları görüntülemektir.
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user