Compare commits
228 Commits
Author | SHA1 | Date | |
---|---|---|---|
62a708b416 | |||
a7ce8704b3 | |||
7319a13077 | |||
95bd4d93c5 | |||
69c33f0395 | |||
cd4caea2dc | |||
c9daf19940 | |||
7c2540b193 | |||
3e600552dc | |||
ba45705571 | |||
bf8ea71c77 | |||
7deb64a5de | |||
e283865d3d | |||
a32be3e96b | |||
0cfd6eab3f | |||
c2361f13e6 | |||
bc81de54b9 | |||
07884bc9b1 | |||
58c3204187 | |||
19d3deddd4 | |||
c6a90a2fd0 | |||
3607c30d98 | |||
717105f243 | |||
a02d4ec46f | |||
485bae8f22 | |||
655477316b | |||
e22f87dee7 | |||
d3337322dd | |||
6202f4f943 | |||
b42cc9ed3e | |||
fbf72c0f61 | |||
cbd0b0c070 | |||
874f049323 | |||
42ab4020e2 | |||
7ab9683b87 | |||
865facfd05 | |||
0951f4a202 | |||
882ec27969 | |||
a84158c1ff | |||
161d3ec817 | |||
5b15249689 | |||
602fce1c7e | |||
f2f653e345 | |||
b55738bd6e | |||
b39a59ce72 | |||
9872daf29f | |||
91044e730b | |||
656a7dceef | |||
d636502eaa | |||
30fa63b379 | |||
691063545c | |||
421934efed | |||
f056b9dc7f | |||
48d421ba28 | |||
096b714117 | |||
0d25dc1aaa | |||
63d3c2d06f | |||
847d71f72a | |||
3c35039445 | |||
1a64d44857 | |||
ba5f0c212c | |||
4eddb5d7f3 | |||
3b104710d5 | |||
74db0004bd | |||
6e67352a0f | |||
b127f02468 | |||
c9c53d9670 | |||
d36dbb868b | |||
b7fb2cfe92 | |||
d0a0c77556 | |||
9469b9c78a | |||
e4988f34c7 | |||
1fe9e24f0a | |||
9c39de3454 | |||
9bb68ad4eb | |||
5bf774bee1 | |||
99514464fb | |||
3bf1c1e531 | |||
e2e31094aa | |||
f29ff15167 | |||
1c64252015 | |||
ead19915f3 | |||
967e0dd98a | |||
bd0324dba0 | |||
607fb83a1e | |||
bb5fc58f3a | |||
afbec0aca9 | |||
1e5d9dfbff | |||
cfcb657cde | |||
7f243e6f06 | |||
7e7032c051 | |||
b7b808d98d | |||
a21289bf11 | |||
4a8d01224a | |||
f0eebc43e3 | |||
49fbf031d1 | |||
4060718e5c | |||
49b0f11ae7 | |||
9b83d35ef4 | |||
eb20add0c7 | |||
1f122e9145 | |||
329d0ecaed | |||
77a2ee948a | |||
ebeda6345e | |||
e35138ebed | |||
8ba6c4f7e7 | |||
6df7b72e08 | |||
fe13b12f43 | |||
ea28da90b2 | |||
b243324c65 | |||
a2dde00f40 | |||
5ff07faa7e | |||
272c652847 | |||
3964bbf3fe | |||
11175aaa5f | |||
7fcc4a7ef0 | |||
5abb9458c7 | |||
0ca5587a6f | |||
d29650882b | |||
9c3a7b02ec | |||
ef3a073af5 | |||
15c4857a4b | |||
63a71afbc8 | |||
64761ee9c6 | |||
d6c344b5ec | |||
d27826d10e | |||
4ac52a0e25 | |||
efa841d75a | |||
d1fac583ea | |||
8cb44c7b97 | |||
f2293a9dda | |||
da0d1d4a2f | |||
6a8d5e2166 | |||
d732665a23 | |||
e0748c9bc7 | |||
23573543a3 | |||
bfb328238e | |||
64cc4f57d6 | |||
7a3c91c6a4 | |||
508bc62852 | |||
59e8446d47 | |||
d13596d2f7 | |||
9adccfa341 | |||
5cc3b53378 | |||
b62b0a2fb7 | |||
1faac4edf2 | |||
4c60dce169 | |||
771f31f44d | |||
8bedb95e1d | |||
ac4be08df2 | |||
0d6e058e23 | |||
bee2ceb667 | |||
6af13d4f40 | |||
9dd0ebd899 | |||
6e97bfa717 | |||
07b69f41eb | |||
6bd2ac7d6d | |||
528e5ef3bc | |||
bc1c50ac92 | |||
8c2ab42b75 | |||
62053d15d4 | |||
6fed642aba | |||
72ac549a58 | |||
9f38617135 | |||
94eec805df | |||
05a940e732 | |||
1c43cc2181 | |||
657ee73ff1 | |||
4ee5d993cf | |||
70a445e2d7 | |||
2115da210d | |||
540554c4f6 | |||
1337c50d28 | |||
c5ceb3b2b1 | |||
57fc1d8f08 | |||
1518ecd1e9 | |||
6be0343918 | |||
cf8812c932 | |||
5bc3e474a9 | |||
13eaa346bc | |||
d7437cc4a7 | |||
ddb3c6590c | |||
89d6773bda | |||
3651b9484f | |||
2200c950b7 | |||
14f84f01b5 | |||
cb014027bb | |||
32e5155783 | |||
a3159ad59e | |||
60a40197f1 | |||
7d693a4271 | |||
f192748bf9 | |||
96f401cba6 | |||
ffd2430160 | |||
190cd2d6bb | |||
7ba58bdbd3 | |||
08ab62108f | |||
1028de8158 | |||
301499dc52 | |||
5c2f13ed8e | |||
e30ad81f69 | |||
21f36f535f | |||
c14236823a | |||
551a9fe1c6 | |||
e3399e1035 | |||
c413b4af3f | |||
dbf5dec23b | |||
10f0eb17d7 | |||
e3b680c351 | |||
0df0545777 | |||
165bfc9f5f | |||
5830bd73b9 | |||
3c4ce839b9 | |||
ac9f052309 | |||
049e424957 | |||
07e78aec48 | |||
3fec135fe5 | |||
867fe1322b | |||
95208a50a7 | |||
514b13fcc2 | |||
4cbc1f5bbe | |||
64de36cdf2 | |||
093b48ad7b | |||
05f6a55a0b | |||
2523424f68 | |||
b81325d7bf | |||
3e10b7b2b1 | |||
e5cb750015 |
5
.github/ISSUE_TEMPLATE/bug_report.md
vendored
5
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -7,6 +7,11 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
**Are you in the right place?**
|
||||||
|
- If you are looking for support on how to get your upstream server forwarding, please consider asking the community on Reddit.
|
||||||
|
- If you are writing code changes to contribute and need to ask about the internals of the software, Gitter is the best place to ask.
|
||||||
|
- If you think you found a bug with NPM (not Nginx, or your upstream server or MySql) then you are in the *right place.*
|
||||||
|
|
||||||
**Checklist**
|
**Checklist**
|
||||||
- Have you pulled and found the error with `jc21/nginx-proxy-manager:latest` docker image?
|
- Have you pulled and found the error with `jc21/nginx-proxy-manager:latest` docker image?
|
||||||
- Are you sure you're not using someone else's docker image?
|
- Are you sure you're not using someone else's docker image?
|
||||||
|
5
.github/ISSUE_TEMPLATE/feature_request.md
vendored
5
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -7,6 +7,11 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
**Are you in the right place?**
|
||||||
|
- If you are looking for support on how to get your upstream server forwarding, please consider asking the community on Reddit.
|
||||||
|
- If you are writing code changes to contribute and need to ask about the internals of the software, Gitter is the best place to ask.
|
||||||
|
- If you have a feature request for NPM then you are in the *right place.*
|
||||||
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
**Is your feature request related to a problem? Please describe.**
|
||||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
16
.github/ISSUE_TEMPLATE/product_support.md
vendored
16
.github/ISSUE_TEMPLATE/product_support.md
vendored
@ -1,16 +0,0 @@
|
|||||||
---
|
|
||||||
name: Product Support
|
|
||||||
about: Need help configuring the software?
|
|
||||||
title: ''
|
|
||||||
labels: product-support
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Checklist**
|
|
||||||
- Please read the [setup instructions](https://nginxproxymanager.com/setup/)
|
|
||||||
- Please read the [FAQ](https://nginxproxymanager.com/faq/)
|
|
||||||
|
|
||||||
**What is troubling you?**
|
|
||||||
|
|
||||||
_Clear and concise description of what you're trying to do and what isn't working for you_
|
|
@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"database": {
|
|
||||||
"engine": "mysql",
|
|
||||||
"host": "db",
|
|
||||||
"name": "npm",
|
|
||||||
"user": "npm",
|
|
||||||
"password": "npm",
|
|
||||||
"port": 3306
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"database": {
|
|
||||||
"engine": "knex-native",
|
|
||||||
"knex": {
|
|
||||||
"client": "sqlite3",
|
|
||||||
"connection": {
|
|
||||||
"filename": "/data/database.sqlite"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
5
Jenkinsfile
vendored
5
Jenkinsfile
vendored
@ -65,6 +65,7 @@ pipeline {
|
|||||||
// See: https://github.com/yarnpkg/yarn/issues/3254
|
// See: https://github.com/yarnpkg/yarn/issues/3254
|
||||||
sh '''docker run --rm \\
|
sh '''docker run --rm \\
|
||||||
-v "$(pwd)/backend:/app" \\
|
-v "$(pwd)/backend:/app" \\
|
||||||
|
-v "$(pwd)/global:/app/global" \\
|
||||||
-w /app \\
|
-w /app \\
|
||||||
node:latest \\
|
node:latest \\
|
||||||
sh -c "yarn install && yarn eslint . && rm -rf node_modules"
|
sh -c "yarn install && yarn eslint . && rm -rf node_modules"
|
||||||
@ -212,7 +213,7 @@ pipeline {
|
|||||||
}
|
}
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
def comment = pullRequest.comment("Docker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker/jc21/${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`")
|
def comment = pullRequest.comment("This is an automated message from CI:\n\nDocker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker/jc21/${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`\n\n**Note:** ensure you backup your NPM instance before testing this PR image! Especially if this PR contains database changes.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,7 +222,7 @@ pipeline {
|
|||||||
always {
|
always {
|
||||||
sh 'docker-compose down --rmi all --remove-orphans --volumes -t 30'
|
sh 'docker-compose down --rmi all --remove-orphans --volumes -t 30'
|
||||||
sh 'echo Reverting ownership'
|
sh 'echo Reverting ownership'
|
||||||
sh 'docker run --rm -v $(pwd):/data ${DOCKER_CI_TOOLS} chown -R $(id -u):$(id -g) /data'
|
sh 'docker run --rm -v $(pwd):/data jc21/ci-tools chown -R $(id -u):$(id -g) /data'
|
||||||
}
|
}
|
||||||
success {
|
success {
|
||||||
juxtapose event: 'success'
|
juxtapose event: 'success'
|
||||||
|
188
README.md
188
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.5.0-green.svg?style=for-the-badge">
|
<img src="https://img.shields.io/badge/version-2.9.2-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>
|
||||||
@ -63,43 +63,43 @@ Special thanks to the following contributors:
|
|||||||
<tr>
|
<tr>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/Subv">
|
<a href="https://github.com/Subv">
|
||||||
<img src="https://avatars1.githubusercontent.com/u/357072?s=460&u=d8adcdc91d749ae53e177973ed9b6bb6c4c894a3&v=4" width="80px;" alt=""/>
|
<img src="https://avatars1.githubusercontent.com/u/357072?s=460&u=d8adcdc91d749ae53e177973ed9b6bb6c4c894a3&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>Sebastian Valle</b></sub>
|
<br /><sub><b>Sebastian Valle</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/Indemnity83">
|
<a href="https://github.com/Indemnity83">
|
||||||
<img src="https://avatars3.githubusercontent.com/u/35218?s=460&u=7082004ff35138157c868d7d9c683ccebfce5968&v=4" width="80px;" alt=""/>
|
<img src="https://avatars3.githubusercontent.com/u/35218?s=460&u=7082004ff35138157c868d7d9c683ccebfce5968&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>Kyle Klaus</b></sub>
|
<br /><sub><b>Kyle Klaus</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/theraw">
|
<a href="https://github.com/theraw">
|
||||||
<img src="https://avatars1.githubusercontent.com/u/32969774?s=460&u=6b359971e15685fb0359e6a8c065a399b40dc228&v=4" width="80px;" alt=""/>
|
<img src="https://avatars1.githubusercontent.com/u/32969774?s=460&u=6b359971e15685fb0359e6a8c065a399b40dc228&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>ƬHE ЯAW</b></sub>
|
<br /><sub><b>ƬHE ЯAW</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/spalger">
|
<a href="https://github.com/spalger">
|
||||||
<img src="https://avatars2.githubusercontent.com/u/1329312?s=400&u=565223e38f1c052afb4c5dcca3fcf1c63ba17ae7&v=4" width="80px;" alt=""/>
|
<img src="https://avatars2.githubusercontent.com/u/1329312?s=400&u=565223e38f1c052afb4c5dcca3fcf1c63ba17ae7&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>Spencer</b></sub>
|
<br /><sub><b>Spencer</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/Xantios">
|
<a href="https://github.com/Xantios">
|
||||||
<img src="https://avatars3.githubusercontent.com/u/1507836?s=460&v=4" width="80px;" alt=""/>
|
<img src="https://avatars3.githubusercontent.com/u/1507836?s=460&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>Xantios Krugor</b></sub>
|
<br /><sub><b>Xantios Krugor</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/dpanesso">
|
<a href="https://github.com/dpanesso">
|
||||||
<img src="https://avatars2.githubusercontent.com/u/2687121?s=460&v=4" width="80px;" alt=""/>
|
<img src="https://avatars2.githubusercontent.com/u/2687121?s=460&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>David Panesso</b></sub>
|
<br /><sub><b>David Panesso</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/IronTooch">
|
<a href="https://github.com/IronTooch">
|
||||||
<img src="https://avatars3.githubusercontent.com/u/27360514?s=460&u=69bf854a6647c55725f62ecb8d39249c6c0b2602&v=4" width="80px;" alt=""/>
|
<img src="https://avatars3.githubusercontent.com/u/27360514?s=460&u=69bf854a6647c55725f62ecb8d39249c6c0b2602&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>IronTooch</b></sub>
|
<br /><sub><b>IronTooch</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
@ -107,43 +107,43 @@ Special thanks to the following contributors:
|
|||||||
<tr>
|
<tr>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/damianog">
|
<a href="https://github.com/damianog">
|
||||||
<img src="https://avatars1.githubusercontent.com/u/2786682?s=460&u=76c6136fae797abb76b951cd8a246dcaecaf21af&v=4" width="80px;" alt=""/>
|
<img src="https://avatars1.githubusercontent.com/u/2786682?s=460&u=76c6136fae797abb76b951cd8a246dcaecaf21af&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>Damiano</b></sub>
|
<br /><sub><b>Damiano</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/tfmm">
|
<a href="https://github.com/tfmm">
|
||||||
<img src="https://avatars3.githubusercontent.com/u/6880538?s=460&u=ce0160821cc4aa802df8395200f2d4956a5bc541&v=4" width="80px;" alt=""/>
|
<img src="https://avatars3.githubusercontent.com/u/6880538?s=460&u=ce0160821cc4aa802df8395200f2d4956a5bc541&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>Russ</b></sub>
|
<br /><sub><b>Russ</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/margaale">
|
<a href="https://github.com/margaale">
|
||||||
<img src="https://avatars3.githubusercontent.com/u/20794934?s=460&v=4" width="80px;" alt=""/>
|
<img src="https://avatars3.githubusercontent.com/u/20794934?s=460&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>Marcelo Castagna</b></sub>
|
<br /><sub><b>Marcelo Castagna</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/Steven-Harris">
|
<a href="https://github.com/Steven-Harris">
|
||||||
<img src="https://avatars2.githubusercontent.com/u/7720242?s=460&v=4" width="80px;" alt=""/>
|
<img src="https://avatars2.githubusercontent.com/u/7720242?s=460&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>Steven Harris</b></sub>
|
<br /><sub><b>Steven Harris</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/jlesage">
|
<a href="https://github.com/jlesage">
|
||||||
<img src="https://avatars0.githubusercontent.com/u/1791123?s=460&v=4" width="80px;" alt=""/>
|
<img src="https://avatars0.githubusercontent.com/u/1791123?s=460&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>Jocelyn Le Sage</b></sub>
|
<br /><sub><b>Jocelyn Le Sage</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/cmer">
|
<a href="https://github.com/cmer">
|
||||||
<img src="https://avatars0.githubusercontent.com/u/412?s=460&u=67dd8b2e3661bfd6f68ec1eaa5b9821bd8a321cd&v=4" width="80px;" alt=""/>
|
<img src="https://avatars0.githubusercontent.com/u/412?s=460&u=67dd8b2e3661bfd6f68ec1eaa5b9821bd8a321cd&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>Carl Mercier</b></sub>
|
<br /><sub><b>Carl Mercier</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/the1ts">
|
<a href="https://github.com/the1ts">
|
||||||
<img src="https://avatars1.githubusercontent.com/u/84956?s=460&v=4" width="80px;" alt=""/>
|
<img src="https://avatars1.githubusercontent.com/u/84956?s=460&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>Paul Mansfield</b></sub>
|
<br /><sub><b>Paul Mansfield</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
@ -151,40 +151,186 @@ Special thanks to the following contributors:
|
|||||||
<tr>
|
<tr>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/OhHeyAlan">
|
<a href="https://github.com/OhHeyAlan">
|
||||||
<img src="https://avatars0.githubusercontent.com/u/11955126?s=460&u=fbaa5a1a4f73ef8960132c703349bfd037fe2630&v=4" width="80px;" alt=""/>
|
<img src="https://avatars0.githubusercontent.com/u/11955126?s=460&u=fbaa5a1a4f73ef8960132c703349bfd037fe2630&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>OhHeyAlan</b></sub>
|
<br /><sub><b>OhHeyAlan</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/dogmatic69">
|
<a href="https://github.com/dogmatic69">
|
||||||
<img src="https://avatars2.githubusercontent.com/u/94674?s=460&u=ca7647de53145c6283b6373ade5dc94ba99347db&v=4" width="80px;" alt=""/>
|
<img src="https://avatars2.githubusercontent.com/u/94674?s=460&u=ca7647de53145c6283b6373ade5dc94ba99347db&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>Carl Sutton</b></sub>
|
<br /><sub><b>Carl Sutton</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/tg44">
|
<a href="https://github.com/tg44">
|
||||||
<img src="https://avatars0.githubusercontent.com/u/31839?s=460&u=ad32f4cadfef5e5fb09cdfa4b7b7b36a99ba6811&v=4" width="80px;" alt=""/>
|
<img src="https://avatars0.githubusercontent.com/u/31839?s=460&u=ad32f4cadfef5e5fb09cdfa4b7b7b36a99ba6811&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>Gergő Törcsvári</b></sub>
|
<br /><sub><b>Gergő Törcsvári</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/vrenjith">
|
<a href="https://github.com/vrenjith">
|
||||||
<img src="https://avatars3.githubusercontent.com/u/2093241?s=460&u=96ce93a9bebabdd0a60a2dc96cd093a41d5edaba&v=4" width="80px;" alt=""/>
|
<img src="https://avatars3.githubusercontent.com/u/2093241?s=460&u=96ce93a9bebabdd0a60a2dc96cd093a41d5edaba&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>vrenjith</b></sub>
|
<br /><sub><b>vrenjith</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/duhruh">
|
<a href="https://github.com/duhruh">
|
||||||
<img src="https://avatars2.githubusercontent.com/u/1133969?s=460&u=c0691e6131ec6d516416c1c6fcedb5034f877bbe&v=4" width="80px;" alt=""/>
|
<img src="https://avatars2.githubusercontent.com/u/1133969?s=460&u=c0691e6131ec6d516416c1c6fcedb5034f877bbe&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>David Rivera</b></sub>
|
<br /><sub><b>David Rivera</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<a href="https://github.com/jipjan">
|
<a href="https://github.com/jipjan">
|
||||||
<img src="https://avatars2.githubusercontent.com/u/1384618?s=460&v=4" width="80px;" alt=""/>
|
<img src="https://avatars2.githubusercontent.com/u/1384618?s=460&v=4" width="80" alt=""/>
|
||||||
<br /><sub><b>Jaap-Jan de Wit</b></sub>
|
<br /><sub><b>Jaap-Jan de Wit</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/jmwebslave">
|
||||||
|
<img src="https://avatars2.githubusercontent.com/u/6118262?s=460&u=7db409c47135b1e141c366bbb03ed9fae6ac2638&v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>James Morgan</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/chaptergy">
|
||||||
|
<img src="https://avatars2.githubusercontent.com/u/26956711?s=460&u=7d9adebabb6b4e7af7cb05d98d751087a372304b&v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>chaptergy</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/Philip-Mooney">
|
||||||
|
<img src="https://avatars0.githubusercontent.com/u/48624631?s=460&v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Philip Mooney</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/WaterCalm">
|
||||||
|
<img src="https://avatars1.githubusercontent.com/u/23502129?s=400&v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>WaterCalm</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/lebrou34">
|
||||||
|
<img src="https://avatars1.githubusercontent.com/u/16373103?s=460&v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>lebrou34</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/lightglitch">
|
||||||
|
<img src="https://avatars0.githubusercontent.com/u/196953?s=460&v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Mário Franco</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/klutchell">
|
||||||
|
<img src="https://avatars3.githubusercontent.com/u/20458272?s=460&v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Kyle Harding</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/ahgraber">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/24922003?s=460&u=8376c9f00af9b6057ba4d2fb03b4f1b20a75277f&v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Alex Graber</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/MooBaloo">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/9493496?s=460&v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>MooBaloo</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/Shuro">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/944030?s=460&v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Shuro</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/lorisbergeron">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/51918567?s=460&u=778e4ff284b7d7304450f98421c99f79298371fb&v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Loris Bergeron</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/hepelayo">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/8243119?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>hepelayo</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/jonasled">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/46790650?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Jonas Leder</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/stegmannb">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/12850482?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Bastian Stegmann</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/Stealthii">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/998920?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Stealthii</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/thegamingninja">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/8020534?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>THEGamingninja</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/italobb">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/1801687?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Italo Borssatto</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/GurjinderSingh">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/3470709?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Gurjinder Singh</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/phantomski77">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/69464125?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>David Dosoudil</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/ijaron">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/5156472?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>ijaron</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/nielscil">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/9073152?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Niels Bouma</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/ogarai">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/2949572?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Orko Garai</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/baruffaldi">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/36949?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Filippo Baruffaldi</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<!-- markdownlint-enable -->
|
<!-- markdownlint-enable -->
|
||||||
|
@ -66,7 +66,7 @@ app.use(function (err, req, res, next) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development' || (req.baseUrl + req.path).includes('nginx/certificates')) {
|
||||||
payload.debug = {
|
payload.debug = {
|
||||||
stack: typeof err.stack !== 'undefined' && err.stack ? err.stack.split('\n') : null,
|
stack: typeof err.stack !== 'undefined' && err.stack ? err.stack.split('\n') : null,
|
||||||
previous: err.previous
|
previous: err.previous
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"knex": {
|
"knex": {
|
||||||
"client": "sqlite3",
|
"client": "sqlite3",
|
||||||
"connection": {
|
"connection": {
|
||||||
"filename": "/app/backend/config/mydb.sqlite"
|
"filename": "/app/config/mydb.sqlite"
|
||||||
},
|
},
|
||||||
"pool": {
|
"pool": {
|
||||||
"min": 0,
|
"min": 0,
|
||||||
|
@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
const logger = require('./logger').global;
|
const logger = require('./logger').global;
|
||||||
|
|
||||||
function appStart () {
|
async function appStart () {
|
||||||
|
// Create config file db settings if environment variables have been set
|
||||||
|
await createDbConfigFromEnvironment();
|
||||||
|
|
||||||
const migrate = require('./migrate');
|
const migrate = require('./migrate');
|
||||||
const setup = require('./setup');
|
const setup = require('./setup');
|
||||||
const app = require('./app');
|
const app = require('./app');
|
||||||
@ -39,9 +42,92 @@ function appStart () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function createDbConfigFromEnvironment() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const envMysqlHost = process.env.DB_MYSQL_HOST || null;
|
||||||
|
const envMysqlPort = process.env.DB_MYSQL_PORT || null;
|
||||||
|
const envMysqlUser = process.env.DB_MYSQL_USER || null;
|
||||||
|
const envMysqlName = process.env.DB_MYSQL_NAME || null;
|
||||||
|
const envSqliteFile = process.env.DB_SQLITE_FILE || null;
|
||||||
|
|
||||||
|
if ((envMysqlHost && envMysqlPort && envMysqlUser && envMysqlName) || envSqliteFile) {
|
||||||
|
const fs = require('fs');
|
||||||
|
const filename = (process.env.NODE_CONFIG_DIR || './config') + '/' + (process.env.NODE_ENV || 'default') + '.json';
|
||||||
|
let configData = {};
|
||||||
|
|
||||||
|
try {
|
||||||
|
configData = require(filename);
|
||||||
|
} catch (err) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configData.database && configData.database.engine && !configData.database.fromEnv) {
|
||||||
|
logger.info('Manual db configuration already exists, skipping config creation from environment variables');
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (envMysqlHost && envMysqlPort && envMysqlUser && envMysqlName) {
|
||||||
|
const newConfig = {
|
||||||
|
fromEnv: true,
|
||||||
|
engine: 'mysql',
|
||||||
|
host: envMysqlHost,
|
||||||
|
port: envMysqlPort,
|
||||||
|
user: envMysqlUser,
|
||||||
|
password: process.env.DB_MYSQL_PASSWORD,
|
||||||
|
name: envMysqlName,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (JSON.stringify(configData.database) === JSON.stringify(newConfig)) {
|
||||||
|
// Config is unchanged, skip overwrite
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info('Generating MySQL db configuration from environment variables');
|
||||||
|
configData.database = newConfig;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const newConfig = {
|
||||||
|
fromEnv: true,
|
||||||
|
engine: 'knex-native',
|
||||||
|
knex: {
|
||||||
|
client: 'sqlite3',
|
||||||
|
connection: {
|
||||||
|
filename: envSqliteFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (JSON.stringify(configData.database) === JSON.stringify(newConfig)) {
|
||||||
|
// Config is unchanged, skip overwrite
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info('Generating Sqlite db configuration from environment variables');
|
||||||
|
configData.database = newConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write config
|
||||||
|
fs.writeFile(filename, JSON.stringify(configData, null, 2), (err) => {
|
||||||
|
if (err) {
|
||||||
|
logger.error('Could not write db config to config file: ' + filename);
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
logger.info('Wrote db configuration to config file: ' + filename);
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
appStart();
|
appStart();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(err.message, err);
|
logger.error(err.message, err);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ const internalAccessList = {
|
|||||||
.insertAndFetch({
|
.insertAndFetch({
|
||||||
name: data.name,
|
name: data.name,
|
||||||
satisfy_any: data.satisfy_any,
|
satisfy_any: data.satisfy_any,
|
||||||
|
pass_auth: data.pass_auth,
|
||||||
owner_user_id: access.token.getUserId(1)
|
owner_user_id: access.token.getUserId(1)
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@ -128,6 +129,7 @@ const internalAccessList = {
|
|||||||
.patch({
|
.patch({
|
||||||
name: data.name,
|
name: data.name,
|
||||||
satisfy_any: data.satisfy_any,
|
satisfy_any: data.satisfy_any,
|
||||||
|
pass_auth: data.pass_auth,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -384,7 +386,7 @@ const internalAccessList = {
|
|||||||
.orderBy('access_list.name', 'ASC');
|
.orderBy('access_list.name', 'ASC');
|
||||||
|
|
||||||
if (access_data.permission_visibility !== 'all') {
|
if (access_data.permission_visibility !== 'all') {
|
||||||
query.andWhere('owner_user_id', access.token.getUserId(1));
|
query.andWhere('access_list.owner_user_id', access.token.getUserId(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query is used for searching
|
// Query is used for searching
|
||||||
|
@ -11,8 +11,9 @@ const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.
|
|||||||
const le_staging = process.env.NODE_ENV !== 'production';
|
const le_staging = process.env.NODE_ENV !== 'production';
|
||||||
const internalNginx = require('./nginx');
|
const internalNginx = require('./nginx');
|
||||||
const internalHost = require('./host');
|
const internalHost = require('./host');
|
||||||
const certbot_command = '/usr/bin/certbot';
|
const certbot_command = '/opt/certbot/bin/certbot';
|
||||||
const le_config = '/etc/letsencrypt.ini';
|
const le_config = '/etc/letsencrypt.ini';
|
||||||
|
const dns_plugins = require('../global/certbot-dns-plugins');
|
||||||
|
|
||||||
function omissions() {
|
function omissions() {
|
||||||
return ['is_deleted'];
|
return ['is_deleted'];
|
||||||
@ -141,11 +142,11 @@ const internalCertificate = {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then((in_use_result) => {
|
.then((in_use_result) => {
|
||||||
// Is CloudFlare, no config needed, so skip 3 and 5.
|
// With DNS challenge no config is needed, so skip 3 and 5.
|
||||||
if (data.meta.cloudflare_use) {
|
if (certificate.meta.dns_challenge) {
|
||||||
return internalNginx.reload().then(() => {
|
return internalNginx.reload().then(() => {
|
||||||
// 4. Request cert
|
// 4. Request cert
|
||||||
return internalCertificate.requestLetsEncryptCloudFlareDnsSsl(certificate, data.meta.cloudflare_token);
|
return internalCertificate.requestLetsEncryptSslWithDnsChallenge(certificate);
|
||||||
})
|
})
|
||||||
.then(internalNginx.reload)
|
.then(internalNginx.reload)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -215,6 +216,13 @@ const internalCertificate = {
|
|||||||
return saved_row;
|
return saved_row;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}).catch(async (error) => {
|
||||||
|
// Delete the certificate from the database if it was not created successfully
|
||||||
|
await certificateModel
|
||||||
|
.query()
|
||||||
|
.deleteById(certificate.id);
|
||||||
|
|
||||||
|
throw error;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return certificate;
|
return certificate;
|
||||||
@ -607,18 +615,26 @@ const internalCertificate = {
|
|||||||
checkPrivateKey: (private_key) => {
|
checkPrivateKey: (private_key) => {
|
||||||
return tempWrite(private_key, '/tmp')
|
return tempWrite(private_key, '/tmp')
|
||||||
.then((filepath) => {
|
.then((filepath) => {
|
||||||
return utils.exec('openssl rsa -in ' + filepath + ' -check -noout')
|
return new Promise((resolve, reject) => {
|
||||||
.then((result) => {
|
const failTimeout = setTimeout(() => {
|
||||||
if (!result.toLowerCase().includes('key ok')) {
|
reject(new error.ValidationError('Result Validation Error: Validation timed out. This could be due to the key being passphrase-protected.'));
|
||||||
throw new error.ValidationError(result);
|
}, 10000);
|
||||||
}
|
utils
|
||||||
|
.exec('openssl pkey -in ' + filepath + ' -check -noout 2>&1 ')
|
||||||
fs.unlinkSync(filepath);
|
.then((result) => {
|
||||||
return true;
|
clearTimeout(failTimeout);
|
||||||
}).catch((err) => {
|
if (!result.toLowerCase().includes('key is valid')) {
|
||||||
fs.unlinkSync(filepath);
|
reject(new error.ValidationError('Result Validation Error: ' + result));
|
||||||
throw new error.ValidationError('Certificate Key is not valid (' + err.message + ')', err);
|
}
|
||||||
});
|
fs.unlinkSync(filepath);
|
||||||
|
resolve(true);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
clearTimeout(failTimeout);
|
||||||
|
fs.unlinkSync(filepath);
|
||||||
|
reject(new error.ValidationError('Certificate Key is not valid (' + err.message + ')', err));
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -772,35 +788,76 @@ const internalCertificate = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} certificate the certificate row
|
* @param {Object} certificate the certificate row
|
||||||
* @param {String} apiToken the cloudflare api token
|
* @param {String} dns_provider the dns provider name (key used in `certbot-dns-plugins.js`)
|
||||||
|
* @param {String | null} credentials the content of this providers credentials file
|
||||||
|
* @param {String} propagation_seconds the cloudflare api token
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
requestLetsEncryptCloudFlareDnsSsl: (certificate, apiToken) => {
|
requestLetsEncryptSslWithDnsChallenge: (certificate) => {
|
||||||
logger.info('Requesting Let\'sEncrypt certificates via Cloudflare DNS for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
const dns_plugin = dns_plugins[certificate.meta.dns_provider];
|
||||||
|
|
||||||
let tokenLoc = '~/cloudflare-token';
|
if (!dns_plugin) {
|
||||||
let storeKey = 'echo "dns_cloudflare_api_token = ' + apiToken + '" > ' + tokenLoc;
|
throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`);
|
||||||
|
}
|
||||||
|
|
||||||
let cmd =
|
logger.info(`Requesting Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
|
||||||
storeKey + ' && ' +
|
|
||||||
|
const credentials_loc = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
|
||||||
|
const credentials_cmd = 'mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo \'' + certificate.meta.dns_provider_credentials.replace('\'', '\\\'') + '\' > \'' + credentials_loc + '\' && chmod 600 \'' + credentials_loc + '\'';
|
||||||
|
const prepare_cmd = 'pip install ' + dns_plugin.package_name + '==' + dns_plugin.package_version + ' ' + dns_plugin.dependencies;
|
||||||
|
|
||||||
|
// Whether the plugin has a --<name>-credentials argument
|
||||||
|
const has_config_arg = certificate.meta.dns_provider !== 'route53' && certificate.meta.dns_provider !== 'duckdns';
|
||||||
|
|
||||||
|
let main_cmd =
|
||||||
certbot_command + ' certonly --non-interactive ' +
|
certbot_command + ' certonly --non-interactive ' +
|
||||||
'--cert-name "npm-' + certificate.id + '" ' +
|
'--cert-name "npm-' + certificate.id + '" ' +
|
||||||
'--agree-tos ' +
|
'--agree-tos ' +
|
||||||
'--email "' + certificate.meta.letsencrypt_email + '" ' +
|
'--email "' + certificate.meta.letsencrypt_email + '" ' +
|
||||||
'--domains "' + certificate.domain_names.join(',') + '" ' +
|
'--domains "' + certificate.domain_names.join(',') + '" ' +
|
||||||
'--dns-cloudflare --dns-cloudflare-credentials ' + tokenLoc +
|
'--authenticator ' + dns_plugin.full_plugin_name + ' ' +
|
||||||
(le_staging ? ' --staging' : '')
|
(
|
||||||
+ ' && rm ' + tokenLoc;
|
has_config_arg
|
||||||
|
? '--' + dns_plugin.full_plugin_name + '-credentials "' + credentials_loc + '"'
|
||||||
|
: ''
|
||||||
|
) +
|
||||||
|
(
|
||||||
|
certificate.meta.propagation_seconds !== undefined
|
||||||
|
? ' --' + dns_plugin.full_plugin_name + '-propagation-seconds ' + certificate.meta.propagation_seconds
|
||||||
|
: ''
|
||||||
|
) +
|
||||||
|
(le_staging ? ' --staging' : '');
|
||||||
|
|
||||||
if (debug_mode) {
|
// Prepend the path to the credentials file as an environment variable
|
||||||
logger.info('Command:', cmd);
|
if (certificate.meta.dns_provider === 'route53') {
|
||||||
|
main_cmd = 'AWS_CONFIG_FILE=\'' + credentials_loc + '\' ' + main_cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.exec(cmd).then((result) => {
|
if (certificate.meta.dns_provider === 'duckdns') {
|
||||||
logger.info(result);
|
main_cmd = main_cmd + ' --' + dns_plugin.full_plugin_name + '-token ' + certificate.meta.dns_provider_credentials;
|
||||||
return result;
|
}
|
||||||
});
|
|
||||||
|
if (debug_mode) {
|
||||||
|
logger.info('Command:', `${credentials_cmd} && ${prepare_cmd} && ${main_cmd}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils.exec(credentials_cmd)
|
||||||
|
.then(() => {
|
||||||
|
return utils.exec(prepare_cmd)
|
||||||
|
.then(() => {
|
||||||
|
return utils.exec(main_cmd)
|
||||||
|
.then(async (result) => {
|
||||||
|
logger.info(result);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}).catch(async (err) => {
|
||||||
|
// Don't fail if file does not exist
|
||||||
|
const delete_credentials_cmd = `rm -f '${credentials_loc}' || true`;
|
||||||
|
await utils.exec(delete_credentials_cmd);
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -817,7 +874,7 @@ const internalCertificate = {
|
|||||||
})
|
})
|
||||||
.then((certificate) => {
|
.then((certificate) => {
|
||||||
if (certificate.provider === 'letsencrypt') {
|
if (certificate.provider === 'letsencrypt') {
|
||||||
let renewMethod = certificate.meta.cloudflare_use ? internalCertificate.renewLetsEncryptCloudFlareSsl : internalCertificate.renewLetsEncryptSsl;
|
let renewMethod = certificate.meta.dns_challenge ? internalCertificate.renewLetsEncryptSslWithDnsChallenge : internalCertificate.renewLetsEncryptSsl;
|
||||||
|
|
||||||
return renewMethod(certificate)
|
return renewMethod(certificate)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -877,20 +934,33 @@ const internalCertificate = {
|
|||||||
* @param {Object} certificate the certificate row
|
* @param {Object} certificate the certificate row
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
renewLetsEncryptCloudFlareSsl: (certificate) => {
|
renewLetsEncryptSslWithDnsChallenge: (certificate) => {
|
||||||
logger.info('Renewing Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
const dns_plugin = dns_plugins[certificate.meta.dns_provider];
|
||||||
|
|
||||||
let cmd = certbot_command + ' renew --non-interactive ' +
|
if (!dns_plugin) {
|
||||||
'--cert-name "npm-' + certificate.id + '" ' +
|
throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`);
|
||||||
'--disable-hook-validation ' +
|
|
||||||
(le_staging ? '--staging' : '');
|
|
||||||
|
|
||||||
if (debug_mode) {
|
|
||||||
logger.info('Command:', cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.exec(cmd)
|
logger.info(`Renewing Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
|
||||||
.then((result) => {
|
|
||||||
|
let main_cmd =
|
||||||
|
certbot_command + ' renew --non-interactive ' +
|
||||||
|
'--cert-name "npm-' + certificate.id + '" ' +
|
||||||
|
'--disable-hook-validation' +
|
||||||
|
(le_staging ? ' --staging' : '');
|
||||||
|
|
||||||
|
// Prepend the path to the credentials file as an environment variable
|
||||||
|
if (certificate.meta.dns_provider === 'route53') {
|
||||||
|
const credentials_loc = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
|
||||||
|
main_cmd = 'AWS_CONFIG_FILE=\'' + credentials_loc + '\' ' + main_cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug_mode) {
|
||||||
|
logger.info('Command:', main_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils.exec(main_cmd)
|
||||||
|
.then(async (result) => {
|
||||||
logger.info(result);
|
logger.info(result);
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
@ -904,20 +974,21 @@ const internalCertificate = {
|
|||||||
revokeLetsEncryptSsl: (certificate, throw_errors) => {
|
revokeLetsEncryptSsl: (certificate, throw_errors) => {
|
||||||
logger.info('Revoking Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
logger.info('Revoking Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
||||||
|
|
||||||
let cmd = certbot_command + ' revoke --non-interactive ' +
|
const main_cmd = certbot_command + ' revoke --non-interactive ' +
|
||||||
'--cert-path "/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' +
|
'--cert-path "/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' +
|
||||||
'--delete-after-revoke ' +
|
'--delete-after-revoke ' +
|
||||||
(le_staging ? '--staging' : '');
|
(le_staging ? '--staging' : '');
|
||||||
|
|
||||||
|
// Don't fail command if file does not exist
|
||||||
|
const delete_credentials_cmd = `rm -f '/etc/letsencrypt/credentials/credentials-${certificate.id}' || true`;
|
||||||
|
|
||||||
if (debug_mode) {
|
if (debug_mode) {
|
||||||
logger.info('Command:', cmd);
|
logger.info('Command:', main_cmd + '; ' + delete_credentials_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.exec(cmd)
|
return utils.exec(main_cmd)
|
||||||
.then((result) => {
|
.then(async (result) => {
|
||||||
if (debug_mode) {
|
await utils.exec(delete_credentials_cmd);
|
||||||
logger.info('Command:', cmd);
|
|
||||||
}
|
|
||||||
logger.info(result);
|
logger.info(result);
|
||||||
return result;
|
return result;
|
||||||
})
|
})
|
||||||
|
@ -106,7 +106,7 @@ const internalHost = {
|
|||||||
response_object.total_count += response_object.redirection_hosts.length;
|
response_object.total_count += response_object.redirection_hosts.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (promises_results[1]) {
|
if (promises_results[2]) {
|
||||||
// Dead Hosts
|
// Dead Hosts
|
||||||
response_object.dead_hosts = internalHost._getHostsWithDomains(promises_results[2], domain_names);
|
response_object.dead_hosts = internalHost._getHostsWithDomains(promises_results[2], domain_names);
|
||||||
response_object.total_count += response_object.dead_hosts.length;
|
response_object.total_count += response_object.dead_hosts.length;
|
||||||
@ -158,7 +158,7 @@ const internalHost = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (promises_results[1]) {
|
if (promises_results[2]) {
|
||||||
// Dead Hosts
|
// Dead Hosts
|
||||||
if (internalHost._checkHostnameRecordsTaken(hostname, promises_results[2], ignore_type === 'dead' && ignore_id ? ignore_id : 0)) {
|
if (internalHost._checkHostnameRecordsTaken(hostname, promises_results[2], ignore_type === 'dead' && ignore_id ? ignore_id : 0)) {
|
||||||
is_taken = true;
|
is_taken = true;
|
||||||
|
@ -189,6 +189,10 @@ const internalProxyHost = {
|
|||||||
expand: ['owner', 'certificate', 'access_list.[clients,items]']
|
expand: ['owner', 'certificate', 'access_list.[clients,items]']
|
||||||
})
|
})
|
||||||
.then((row) => {
|
.then((row) => {
|
||||||
|
if (!row.enabled) {
|
||||||
|
// No need to add nginx config if host is disabled
|
||||||
|
return row;
|
||||||
|
}
|
||||||
// Configure nginx
|
// Configure nginx
|
||||||
return internalNginx.configure(proxyHostModel, 'proxy_host', row)
|
return internalNginx.configure(proxyHostModel, 'proxy_host', row)
|
||||||
.then((new_meta) => {
|
.then((new_meta) => {
|
||||||
|
41
backend/migrations/20201014143841_pass_auth.js
Normal file
41
backend/migrations/20201014143841_pass_auth.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
const migrate_name = 'pass_auth';
|
||||||
|
const logger = require('../logger').migrate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate
|
||||||
|
*
|
||||||
|
* @see http://knexjs.org/#Schema
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.up = function (knex/*, Promise*/) {
|
||||||
|
|
||||||
|
logger.info('[' + migrate_name + '] Migrating Up...');
|
||||||
|
|
||||||
|
return knex.schema.table('access_list', function (access_list) {
|
||||||
|
access_list.integer('pass_auth').notNull().defaultTo(1);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
logger.info('[' + migrate_name + '] access_list Table altered');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo Migrate
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.down = function (knex/*, Promise*/) {
|
||||||
|
logger.info('[' + migrate_name + '] Migrating Down...');
|
||||||
|
|
||||||
|
return knex.schema.table('access_list', function (access_list) {
|
||||||
|
access_list.dropColumn('pass_auth');
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
logger.info('[' + migrate_name + '] access_list pass_auth Column dropped');
|
||||||
|
});
|
||||||
|
};
|
41
backend/migrations/20210210154702_redirection_scheme.js
Normal file
41
backend/migrations/20210210154702_redirection_scheme.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
const migrate_name = 'redirection_scheme';
|
||||||
|
const logger = require('../logger').migrate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate
|
||||||
|
*
|
||||||
|
* @see http://knexjs.org/#Schema
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.up = function (knex/*, Promise*/) {
|
||||||
|
|
||||||
|
logger.info('[' + migrate_name + '] Migrating Up...');
|
||||||
|
|
||||||
|
return knex.schema.table('redirection_host', (table) => {
|
||||||
|
table.string('forward_scheme').notNull().defaultTo('$scheme');
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
logger.info('[' + migrate_name + '] redirection_host Table altered');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo Migrate
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.down = function (knex/*, Promise*/) {
|
||||||
|
logger.info('[' + migrate_name + '] Migrating Down...');
|
||||||
|
|
||||||
|
return knex.schema.table('redirection_host', (table) => {
|
||||||
|
table.dropColumn('forward_scheme');
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
logger.info('[' + migrate_name + '] redirection_host Table altered');
|
||||||
|
});
|
||||||
|
};
|
41
backend/migrations/20210210154703_redirection_status_code.js
Normal file
41
backend/migrations/20210210154703_redirection_status_code.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
const migrate_name = 'redirection_status_code';
|
||||||
|
const logger = require('../logger').migrate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate
|
||||||
|
*
|
||||||
|
* @see http://knexjs.org/#Schema
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.up = function (knex/*, Promise*/) {
|
||||||
|
|
||||||
|
logger.info('[' + migrate_name + '] Migrating Up...');
|
||||||
|
|
||||||
|
return knex.schema.table('redirection_host', (table) => {
|
||||||
|
table.integer('forward_http_code').notNull().unsigned().defaultTo(302);
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
logger.info('[' + migrate_name + '] redirection_host Table altered');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo Migrate
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.down = function (knex/*, Promise*/) {
|
||||||
|
logger.info('[' + migrate_name + '] Migrating Down...');
|
||||||
|
|
||||||
|
return knex.schema.table('redirection_host', (table) => {
|
||||||
|
table.dropColumn('forward_http_code');
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
logger.info('[' + migrate_name + '] redirection_host Table altered');
|
||||||
|
});
|
||||||
|
};
|
@ -93,6 +93,10 @@ class AccessList extends Model {
|
|||||||
get satisfy() {
|
get satisfy() {
|
||||||
return this.satisfy_any ? 'satisfy any' : 'satisfy all';
|
return this.satisfy_any ? 'satisfy any' : 'satisfy all';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get passauth() {
|
||||||
|
return this.pass_auth ? '' : 'proxy_set_header Authorization "";';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = AccessList;
|
module.exports = AccessList;
|
||||||
|
@ -4,15 +4,23 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const config = require('config');
|
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const error = require('../lib/error');
|
const error = require('../lib/error');
|
||||||
const ALGO = 'RS256';
|
const ALGO = 'RS256';
|
||||||
|
|
||||||
|
let public_key = null;
|
||||||
|
let private_key = null;
|
||||||
|
|
||||||
|
function checkJWTKeyPair() {
|
||||||
|
if (!public_key || !private_key) {
|
||||||
|
let config = require('config');
|
||||||
|
public_key = config.get('jwt.pub');
|
||||||
|
private_key = config.get('jwt.key');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = function () {
|
module.exports = function () {
|
||||||
const public_key = config.get('jwt.pub');
|
|
||||||
const private_key = config.get('jwt.key');
|
|
||||||
|
|
||||||
let token_data = {};
|
let token_data = {};
|
||||||
|
|
||||||
@ -32,6 +40,8 @@ module.exports = function () {
|
|||||||
.toString('base64')
|
.toString('base64')
|
||||||
.substr(-8);
|
.substr(-8);
|
||||||
|
|
||||||
|
checkJWTKeyPair();
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
jwt.sign(payload, private_key, options, (err, token) => {
|
jwt.sign(payload, private_key, options, (err, token) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -53,6 +63,7 @@ module.exports = function () {
|
|||||||
*/
|
*/
|
||||||
load: function (token) {
|
load: function (token) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
checkJWTKeyPair();
|
||||||
try {
|
try {
|
||||||
if (!token || token === null || token === 'null') {
|
if (!token || token === null || token === 'null') {
|
||||||
reject(new error.AuthError('Empty token'));
|
reject(new error.AuthError('Empty token'));
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"knex": "^0.20.13",
|
"knex": "^0.20.13",
|
||||||
"liquidjs": "^9.11.10",
|
"liquidjs": "^9.11.10",
|
||||||
"lodash": "^4.17.19",
|
"lodash": "^4.17.21",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
"node-rsa": "^1.0.8",
|
"node-rsa": "^1.0.8",
|
||||||
|
@ -58,6 +58,7 @@ router
|
|||||||
.post((req, res, next) => {
|
.post((req, res, next) => {
|
||||||
apiValidator({$ref: 'endpoints/certificates#/links/1/schema'}, req.body)
|
apiValidator({$ref: 'endpoints/certificates#/links/1/schema'}, req.body)
|
||||||
.then((payload) => {
|
.then((payload) => {
|
||||||
|
req.setTimeout(900000); // 15 minutes timeout
|
||||||
return internalCertificate.create(res.locals.access, payload);
|
return internalCertificate.create(res.locals.access, payload);
|
||||||
})
|
})
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
@ -197,6 +198,7 @@ router
|
|||||||
* Renew certificate
|
* Renew certificate
|
||||||
*/
|
*/
|
||||||
.post((req, res, next) => {
|
.post((req, res, next) => {
|
||||||
|
req.setTimeout(900000); // 15 minutes timeout
|
||||||
internalCertificate.renew(res.locals.access, {
|
internalCertificate.renew(res.locals.access, {
|
||||||
id: parseInt(req.params.certificate_id, 10)
|
id: parseInt(req.params.certificate_id, 10)
|
||||||
})
|
})
|
||||||
|
@ -179,6 +179,19 @@
|
|||||||
"pattern": "^(?:\\*\\.)?(?:[^.*]+\\.?)+[^.]$"
|
"pattern": "^(?:\\*\\.)?(?:[^.*]+\\.?)+[^.]$"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"http_code": {
|
||||||
|
"description": "Redirect HTTP Status Code",
|
||||||
|
"example": 302,
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 300,
|
||||||
|
"maximum": 308
|
||||||
|
},
|
||||||
|
"scheme": {
|
||||||
|
"description": "RFC Protocol",
|
||||||
|
"example": "HTTPS or $scheme",
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 4
|
||||||
|
},
|
||||||
"enabled": {
|
"enabled": {
|
||||||
"description": "Is Enabled",
|
"description": "Is Enabled",
|
||||||
"example": true,
|
"example": true,
|
||||||
|
@ -42,6 +42,9 @@
|
|||||||
"satisfy_any": {
|
"satisfy_any": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"pass_auth": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"meta": {
|
"meta": {
|
||||||
"type": "object"
|
"type": "object"
|
||||||
}
|
}
|
||||||
@ -102,6 +105,9 @@
|
|||||||
"satisfy_any": {
|
"satisfy_any": {
|
||||||
"$ref": "#/definitions/satisfy_any"
|
"$ref": "#/definitions/satisfy_any"
|
||||||
},
|
},
|
||||||
|
"pass_auth": {
|
||||||
|
"$ref": "#/definitions/pass_auth"
|
||||||
|
},
|
||||||
"items": {
|
"items": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"minItems": 0,
|
"minItems": 0,
|
||||||
@ -167,6 +173,9 @@
|
|||||||
"satisfy_any": {
|
"satisfy_any": {
|
||||||
"$ref": "#/definitions/satisfy_any"
|
"$ref": "#/definitions/satisfy_any"
|
||||||
},
|
},
|
||||||
|
"pass_auth": {
|
||||||
|
"$ref": "#/definitions/pass_auth"
|
||||||
|
},
|
||||||
"items": {
|
"items": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"minItems": 0,
|
"minItems": 0,
|
||||||
|
@ -42,11 +42,23 @@
|
|||||||
"letsencrypt_agree": {
|
"letsencrypt_agree": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"cloudflare_use": {
|
"dns_challenge": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"cloudflare_token": {
|
"dns_provider": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"dns_provider_credentials": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"propagation_seconds": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,12 @@
|
|||||||
"domain_names": {
|
"domain_names": {
|
||||||
"$ref": "../definitions.json#/definitions/domain_names"
|
"$ref": "../definitions.json#/definitions/domain_names"
|
||||||
},
|
},
|
||||||
|
"forward_http_code": {
|
||||||
|
"$ref": "../definitions.json#/definitions/http_code"
|
||||||
|
},
|
||||||
|
"forward_scheme": {
|
||||||
|
"$ref": "../definitions.json#/definitions/scheme"
|
||||||
|
},
|
||||||
"forward_domain_name": {
|
"forward_domain_name": {
|
||||||
"$ref": "../definitions.json#/definitions/domain_name"
|
"$ref": "../definitions.json#/definitions/domain_name"
|
||||||
},
|
},
|
||||||
@ -67,6 +73,12 @@
|
|||||||
"domain_names": {
|
"domain_names": {
|
||||||
"$ref": "#/definitions/domain_names"
|
"$ref": "#/definitions/domain_names"
|
||||||
},
|
},
|
||||||
|
"forward_http_code": {
|
||||||
|
"$ref": "#/definitions/forward_http_code"
|
||||||
|
},
|
||||||
|
"forward_scheme": {
|
||||||
|
"$ref": "#/definitions/forward_scheme"
|
||||||
|
},
|
||||||
"forward_domain_name": {
|
"forward_domain_name": {
|
||||||
"$ref": "#/definitions/forward_domain_name"
|
"$ref": "#/definitions/forward_domain_name"
|
||||||
},
|
},
|
||||||
@ -134,12 +146,20 @@
|
|||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"required": [
|
"required": [
|
||||||
"domain_names",
|
"domain_names",
|
||||||
|
"forward_scheme",
|
||||||
|
"forward_http_code",
|
||||||
"forward_domain_name"
|
"forward_domain_name"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"domain_names": {
|
"domain_names": {
|
||||||
"$ref": "#/definitions/domain_names"
|
"$ref": "#/definitions/domain_names"
|
||||||
},
|
},
|
||||||
|
"forward_http_code": {
|
||||||
|
"$ref": "#/definitions/forward_http_code"
|
||||||
|
},
|
||||||
|
"forward_scheme": {
|
||||||
|
"$ref": "#/definitions/forward_scheme"
|
||||||
|
},
|
||||||
"forward_domain_name": {
|
"forward_domain_name": {
|
||||||
"$ref": "#/definitions/forward_domain_name"
|
"$ref": "#/definitions/forward_domain_name"
|
||||||
},
|
},
|
||||||
@ -195,6 +215,12 @@
|
|||||||
"domain_names": {
|
"domain_names": {
|
||||||
"$ref": "#/definitions/domain_names"
|
"$ref": "#/definitions/domain_names"
|
||||||
},
|
},
|
||||||
|
"forward_http_code": {
|
||||||
|
"$ref": "#/definitions/forward_http_code"
|
||||||
|
},
|
||||||
|
"forward_scheme": {
|
||||||
|
"$ref": "#/definitions/forward_scheme"
|
||||||
|
},
|
||||||
"forward_domain_name": {
|
"forward_domain_name": {
|
||||||
"$ref": "#/definitions/forward_domain_name"
|
"$ref": "#/definitions/forward_domain_name"
|
||||||
},
|
},
|
||||||
|
@ -2,10 +2,13 @@ const fs = require('fs');
|
|||||||
const NodeRSA = require('node-rsa');
|
const NodeRSA = require('node-rsa');
|
||||||
const config = require('config');
|
const config = require('config');
|
||||||
const logger = require('./logger').setup;
|
const logger = require('./logger').setup;
|
||||||
|
const certificateModel = require('./models/certificate');
|
||||||
const userModel = require('./models/user');
|
const userModel = require('./models/user');
|
||||||
const userPermissionModel = require('./models/user_permission');
|
const userPermissionModel = require('./models/user_permission');
|
||||||
|
const utils = require('./lib/utils');
|
||||||
const authModel = require('./models/auth');
|
const authModel = require('./models/auth');
|
||||||
const settingModel = require('./models/setting');
|
const settingModel = require('./models/setting');
|
||||||
|
const dns_plugins = require('./global/certbot-dns-plugins');
|
||||||
const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG;
|
const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,9 +51,8 @@ const setupJwt = () => {
|
|||||||
reject(err);
|
reject(err);
|
||||||
} else {
|
} else {
|
||||||
logger.info('Wrote JWT key pair to config file: ' + filename);
|
logger.info('Wrote JWT key pair to config file: ' + filename);
|
||||||
|
delete require.cache[require.resolve('config')];
|
||||||
logger.warn('Restarting interface to apply new configuration');
|
resolve();
|
||||||
process.exit(0);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -155,8 +157,53 @@ const setupDefaultSettings = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Installs all Certbot plugins which are required for an installed certificate
|
||||||
|
*
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
const setupCertbotPlugins = () => {
|
||||||
|
return certificateModel
|
||||||
|
.query()
|
||||||
|
.where('is_deleted', 0)
|
||||||
|
.andWhere('provider', 'letsencrypt')
|
||||||
|
.then((certificates) => {
|
||||||
|
if (certificates && certificates.length) {
|
||||||
|
let plugins = [];
|
||||||
|
let promises = [];
|
||||||
|
|
||||||
|
certificates.map(function (certificate) {
|
||||||
|
if (certificate.meta && certificate.meta.dns_challenge === true) {
|
||||||
|
const dns_plugin = dns_plugins[certificate.meta.dns_provider];
|
||||||
|
const packages_to_install = `${dns_plugin.package_name}==${dns_plugin.package_version} ${dns_plugin.dependencies}`;
|
||||||
|
|
||||||
|
if (plugins.indexOf(packages_to_install) === -1) plugins.push(packages_to_install);
|
||||||
|
|
||||||
|
// Make sure credentials file exists
|
||||||
|
const credentials_loc = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
|
||||||
|
const credentials_cmd = '[ -f \'' + credentials_loc + '\' ] || { mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo \'' + certificate.meta.dns_provider_credentials.replace('\'', '\\\'') + '\' > \'' + credentials_loc + '\' && chmod 600 \'' + credentials_loc + '\'; }';
|
||||||
|
promises.push(utils.exec(credentials_cmd));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (plugins.length) {
|
||||||
|
const install_cmd = 'pip install ' + plugins.join(' ');
|
||||||
|
promises.push(utils.exec(install_cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (promises.length) {
|
||||||
|
return Promise.all(promises)
|
||||||
|
.then(() => {
|
||||||
|
logger.info('Added Certbot plugins ' + plugins.join(', '));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = function () {
|
module.exports = function () {
|
||||||
return setupJwt()
|
return setupJwt()
|
||||||
.then(setupDefaultUser)
|
.then(setupDefaultUser)
|
||||||
.then(setupDefaultSettings);
|
.then(setupDefaultSettings)
|
||||||
|
.then(setupCertbotPlugins);
|
||||||
};
|
};
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
{% 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 %}
|
||||||
{% if hsts_enabled == 1 or hsts_enabled == true %}
|
{% if hsts_enabled == 1 or hsts_enabled == true %}
|
||||||
# HSTS (ngx_http_headers_module is required) (31536000 seconds = 1 year)
|
# HSTS (ngx_http_headers_module is required) (63072000 seconds = 2 years)
|
||||||
add_header Strict-Transport-Security "max-age=31536000;{% if hsts_subdomains == 1 or hsts_subdomains == true -%} includeSubDomains;{% endif %} preload" always;
|
add_header Strict-Transport-Security "max-age=63072000;{% if hsts_subdomains == 1 or hsts_subdomains == true -%} includeSubDomains;{% endif %} preload" always;
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
|
@ -5,6 +5,7 @@ server {
|
|||||||
{% include "_listen.conf" %}
|
{% include "_listen.conf" %}
|
||||||
{% include "_certificates.conf" %}
|
{% include "_certificates.conf" %}
|
||||||
{% include "_hsts.conf" %}
|
{% include "_hsts.conf" %}
|
||||||
|
{% include "_forced_ssl.conf" %}
|
||||||
|
|
||||||
access_log /data/logs/dead_host-{{ id }}.log standard;
|
access_log /data/logs/dead_host-{{ id }}.log standard;
|
||||||
|
|
||||||
@ -12,7 +13,6 @@ server {
|
|||||||
|
|
||||||
{% if use_default_location %}
|
{% if use_default_location %}
|
||||||
location / {
|
location / {
|
||||||
{% include "_forced_ssl.conf" %}
|
|
||||||
{% include "_hsts.conf" %}
|
{% include "_hsts.conf" %}
|
||||||
return 404;
|
return 404;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,11 @@
|
|||||||
{%- else %}
|
{%- else %}
|
||||||
server {
|
server {
|
||||||
listen 80 default;
|
listen 80 default;
|
||||||
|
{% if ipv6 -%}
|
||||||
|
listen [::]:80;
|
||||||
|
{% else -%}
|
||||||
|
#listen [::]:80;
|
||||||
|
{% endif %}
|
||||||
server_name default-host.localhost;
|
server_name default-host.localhost;
|
||||||
access_log /data/logs/default_host.log combined;
|
access_log /data/logs/default_host.log combined;
|
||||||
{% include "_exploits.conf" %}
|
{% include "_exploits.conf" %}
|
||||||
|
@ -11,6 +11,14 @@ server {
|
|||||||
{% include "_assets.conf" %}
|
{% include "_assets.conf" %}
|
||||||
{% include "_exploits.conf" %}
|
{% include "_exploits.conf" %}
|
||||||
{% include "_hsts.conf" %}
|
{% include "_hsts.conf" %}
|
||||||
|
{% include "_forced_ssl.conf" %}
|
||||||
|
|
||||||
|
{% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %}
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $http_connection;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
access_log /data/logs/proxy_host-{{ id }}.log proxy;
|
access_log /data/logs/proxy_host-{{ id }}.log proxy;
|
||||||
|
|
||||||
@ -27,6 +35,8 @@ server {
|
|||||||
# Authorization
|
# Authorization
|
||||||
auth_basic "Authorization required";
|
auth_basic "Authorization required";
|
||||||
auth_basic_user_file /data/access/{{ access_list_id }};
|
auth_basic_user_file /data/access/{{ access_list_id }};
|
||||||
|
|
||||||
|
{{ access_list.passauth }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
# Access Rules
|
# Access Rules
|
||||||
@ -35,11 +45,12 @@ server {
|
|||||||
{% endfor %}deny all;
|
{% endfor %}deny all;
|
||||||
|
|
||||||
# Access checks must...
|
# Access checks must...
|
||||||
|
{% if access_list.satisfy %}
|
||||||
{{ access_list.satisfy }};
|
{{ access_list.satisfy }};
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% include "_forced_ssl.conf" %}
|
|
||||||
{% include "_hsts.conf" %}
|
{% include "_hsts.conf" %}
|
||||||
|
|
||||||
{% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %}
|
{% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %}
|
||||||
|
@ -7,6 +7,7 @@ server {
|
|||||||
{% include "_assets.conf" %}
|
{% include "_assets.conf" %}
|
||||||
{% include "_exploits.conf" %}
|
{% include "_exploits.conf" %}
|
||||||
{% include "_hsts.conf" %}
|
{% include "_hsts.conf" %}
|
||||||
|
{% include "_forced_ssl.conf" %}
|
||||||
|
|
||||||
access_log /data/logs/redirection_host-{{ id }}.log standard;
|
access_log /data/logs/redirection_host-{{ id }}.log standard;
|
||||||
|
|
||||||
@ -14,13 +15,12 @@ server {
|
|||||||
|
|
||||||
{% if use_default_location %}
|
{% if use_default_location %}
|
||||||
location / {
|
location / {
|
||||||
{% include "_forced_ssl.conf" %}
|
|
||||||
{% include "_hsts.conf" %}
|
{% include "_hsts.conf" %}
|
||||||
|
|
||||||
{% if preserve_path == 1 or preserve_path == true %}
|
{% if preserve_path == 1 or preserve_path == true %}
|
||||||
return 301 $scheme://{{ forward_domain_name }}$request_uri;
|
return {{ forward_http_code }} {{ forward_scheme }}://{{ forward_domain_name }}$request_uri;
|
||||||
{% else %}
|
{% else %}
|
||||||
return 301 $scheme://{{ forward_domain_name }};
|
return {{ forward_http_code }} {{ forward_scheme }}://{{ forward_domain_name }};
|
||||||
{% endif %}
|
{% endif %}
|
||||||
}
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -1548,9 +1548,9 @@ inherits@2.0.3:
|
|||||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||||
|
|
||||||
ini@^1.3.4, ini@^1.3.5, ini@~1.3.0:
|
ini@^1.3.4, ini@^1.3.5, ini@~1.3.0:
|
||||||
version "1.3.5"
|
version "1.3.8"
|
||||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
|
||||||
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
|
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
|
||||||
|
|
||||||
inquirer@^7.0.0:
|
inquirer@^7.0.0:
|
||||||
version "7.3.3"
|
version "7.3.3"
|
||||||
@ -2024,10 +2024,10 @@ lodash.once@^4.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
||||||
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
|
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
|
||||||
|
|
||||||
lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19:
|
lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21:
|
||||||
version "4.17.19"
|
version "4.17.21"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
|
|
||||||
lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
|
lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
@ -3717,9 +3717,9 @@ xtend@^4.0.0:
|
|||||||
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||||
|
|
||||||
y18n@^4.0.0:
|
y18n@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
|
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4"
|
||||||
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
|
integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==
|
||||||
|
|
||||||
yallist@^3.0.0, yallist@^3.0.3:
|
yallist@^3.0.0, yallist@^3.0.3:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
|
@ -3,45 +3,54 @@
|
|||||||
|
|
||||||
# This file assumes that the frontend has been built using ./scripts/frontend-build
|
# This file assumes that the frontend has been built using ./scripts/frontend-build
|
||||||
|
|
||||||
FROM --platform=${TARGETPLATFORM:-linux/amd64} jc21/alpine-nginx-full:node
|
FROM jc21/nginx-full:node
|
||||||
|
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
ARG BUILDPLATFORM
|
|
||||||
ARG BUILD_VERSION
|
ARG BUILD_VERSION
|
||||||
ARG BUILD_COMMIT
|
ARG BUILD_COMMIT
|
||||||
ARG BUILD_DATE
|
ARG BUILD_DATE
|
||||||
|
|
||||||
ENV SUPPRESS_NO_CONFIG_WARNING=1
|
ENV SUPPRESS_NO_CONFIG_WARNING=1 \
|
||||||
ENV S6_FIX_ATTRS_HIDDEN=1
|
S6_FIX_ATTRS_HIDDEN=1 \
|
||||||
ENV NODE_ENV=production
|
S6_BEHAVIOUR_IF_STAGE2_FAILS=1 \
|
||||||
|
NODE_ENV=production \
|
||||||
|
NPM_BUILD_VERSION="${BUILD_VERSION}" \
|
||||||
|
NPM_BUILD_COMMIT="${BUILD_COMMIT}" \
|
||||||
|
NPM_BUILD_DATE="${BUILD_DATE}"
|
||||||
|
|
||||||
RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
|
RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
|
||||||
&& apk update \
|
&& apt-get update \
|
||||||
&& apk add python2 py-pip certbot jq \
|
&& apt-get install -y --no-install-recommends jq \
|
||||||
&& pip install certbot-dns-cloudflare \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/cache/apk/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
ENV NPM_BUILD_VERSION="${BUILD_VERSION}" NPM_BUILD_COMMIT="${BUILD_COMMIT}" NPM_BUILD_DATE="${BUILD_DATE}"
|
|
||||||
|
|
||||||
# s6 overlay
|
# s6 overlay
|
||||||
COPY scripts/install-s6 /tmp/install-s6
|
COPY scripts/install-s6 /tmp/install-s6
|
||||||
RUN /tmp/install-s6 "${TARGETPLATFORM}" && rm -f /tmp/install-s6
|
RUN /tmp/install-s6 "${TARGETPLATFORM}" && rm -f /tmp/install-s6
|
||||||
|
|
||||||
EXPOSE 80
|
EXPOSE 80 81 443
|
||||||
EXPOSE 81
|
|
||||||
EXPOSE 443
|
|
||||||
|
|
||||||
COPY docker/rootfs /
|
COPY backend /app
|
||||||
ADD backend /app
|
COPY frontend/dist /app/frontend
|
||||||
ADD frontend/dist /app/frontend
|
COPY global /app/global
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN yarn install
|
RUN yarn install
|
||||||
|
|
||||||
|
# add late to limit cache-busting by modifications
|
||||||
|
COPY docker/rootfs /
|
||||||
|
|
||||||
# Remove frontend service not required for prod, dev nginx config as well
|
# Remove frontend service not required for prod, dev nginx config as well
|
||||||
RUN rm -rf /etc/services.d/frontend RUN rm -f /etc/nginx/conf.d/dev.conf
|
RUN rm -rf /etc/services.d/frontend /etc/nginx/conf.d/dev.conf
|
||||||
|
|
||||||
VOLUME [ "/data", "/etc/letsencrypt" ]
|
VOLUME [ "/data", "/etc/letsencrypt" ]
|
||||||
CMD [ "/init" ]
|
ENTRYPOINT [ "/init" ]
|
||||||
|
|
||||||
HEALTHCHECK --interval=5s --timeout=3s CMD /bin/check-health
|
HEALTHCHECK --interval=5s --timeout=3s CMD /bin/check-health
|
||||||
|
|
||||||
|
LABEL org.label-schema.schema-version="1.0" \
|
||||||
|
org.label-schema.license="MIT" \
|
||||||
|
org.label-schema.name="nginx-proxy-manager" \
|
||||||
|
org.label-schema.description="Docker container for managing Nginx proxy hosts with a simple, powerful interface " \
|
||||||
|
org.label-schema.url="https://github.com/jc21/nginx-proxy-manager" \
|
||||||
|
org.label-schema.vcs-url="https://github.com/jc21/nginx-proxy-manager.git" \
|
||||||
|
org.label-schema.cmd="docker run --rm -ti jc21/nginx-proxy-manager:latest"
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
FROM jc21/alpine-nginx-full:node
|
FROM jc21/nginx-full:node
|
||||||
LABEL maintainer="Jamie Curnow <jc@jc21.com>"
|
LABEL maintainer="Jamie Curnow <jc@jc21.com>"
|
||||||
|
|
||||||
ENV S6_LOGGING=0
|
ENV S6_LOGGING=0 \
|
||||||
ENV SUPPRESS_NO_CONFIG_WARNING=1
|
SUPPRESS_NO_CONFIG_WARNING=1 \
|
||||||
ENV S6_FIX_ATTRS_HIDDEN=1
|
S6_FIX_ATTRS_HIDDEN=1
|
||||||
|
|
||||||
RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
|
RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
|
||||||
&& apk update \
|
&& apt-get update \
|
||||||
&& apk add python2 py-pip certbot jq \
|
&& apt-get install -y certbot jq python3-pip \
|
||||||
&& pip install certbot-dns-cloudflare \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/cache/apk/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Task
|
# Task
|
||||||
RUN cd /usr \
|
RUN cd /usr \
|
||||||
@ -23,10 +23,6 @@ RUN rm -f /etc/nginx/conf.d/production.conf
|
|||||||
RUN curl -L -o /tmp/s6-overlay-amd64.tar.gz "https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-amd64.tar.gz" \
|
RUN curl -L -o /tmp/s6-overlay-amd64.tar.gz "https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-amd64.tar.gz" \
|
||||||
&& tar -xzf /tmp/s6-overlay-amd64.tar.gz -C /
|
&& tar -xzf /tmp/s6-overlay-amd64.tar.gz -C /
|
||||||
|
|
||||||
EXPOSE 80
|
EXPOSE 80 81 443
|
||||||
EXPOSE 81
|
ENTRYPOINT [ "/init" ]
|
||||||
EXPOSE 443
|
|
||||||
|
|
||||||
CMD [ "/init" ]
|
|
||||||
|
|
||||||
HEALTHCHECK --interval=5s --timeout=3s CMD /bin/check-health
|
HEALTHCHECK --interval=5s --timeout=3s CMD /bin/check-health
|
||||||
|
@ -5,11 +5,15 @@ services:
|
|||||||
fullstack-mysql:
|
fullstack-mysql:
|
||||||
image: ${IMAGE}:ci-${BUILD_NUMBER}
|
image: ${IMAGE}:ci-${BUILD_NUMBER}
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=development
|
NODE_ENV: "development"
|
||||||
- FORCE_COLOR=1
|
FORCE_COLOR: 1
|
||||||
|
DB_MYSQL_HOST: "db"
|
||||||
|
DB_MYSQL_PORT: 3306
|
||||||
|
DB_MYSQL_USER: "npm"
|
||||||
|
DB_MYSQL_PASSWORD: "npm"
|
||||||
|
DB_MYSQL_NAME: "npm"
|
||||||
volumes:
|
volumes:
|
||||||
- npm_data:/data
|
- npm_data:/data
|
||||||
- ../.jenkins/config-mysql.json:/app/config/development.json
|
|
||||||
expose:
|
expose:
|
||||||
- 81
|
- 81
|
||||||
- 80
|
- 80
|
||||||
@ -20,11 +24,11 @@ services:
|
|||||||
fullstack-sqlite:
|
fullstack-sqlite:
|
||||||
image: ${IMAGE}:ci-${BUILD_NUMBER}
|
image: ${IMAGE}:ci-${BUILD_NUMBER}
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=development
|
NODE_ENV: "development"
|
||||||
- FORCE_COLOR=1
|
FORCE_COLOR: 1
|
||||||
|
DB_SQLITE_FILE: "/data/database.sqlite"
|
||||||
volumes:
|
volumes:
|
||||||
- npm_data:/data
|
- npm_data:/data
|
||||||
- ../.jenkins/config-sqlite.json:/app/config/development.json
|
|
||||||
expose:
|
expose:
|
||||||
- 81
|
- 81
|
||||||
- 80
|
- 80
|
||||||
@ -43,8 +47,8 @@ services:
|
|||||||
cypress-mysql:
|
cypress-mysql:
|
||||||
image: ${IMAGE}-cypress:ci-${BUILD_NUMBER}
|
image: ${IMAGE}-cypress:ci-${BUILD_NUMBER}
|
||||||
build:
|
build:
|
||||||
context: ../
|
context: ../test/
|
||||||
dockerfile: test/cypress/Dockerfile
|
dockerfile: cypress/Dockerfile
|
||||||
environment:
|
environment:
|
||||||
CYPRESS_baseUrl: "http://fullstack-mysql:81"
|
CYPRESS_baseUrl: "http://fullstack-mysql:81"
|
||||||
volumes:
|
volumes:
|
||||||
@ -54,8 +58,8 @@ services:
|
|||||||
cypress-sqlite:
|
cypress-sqlite:
|
||||||
image: ${IMAGE}-cypress:ci-${BUILD_NUMBER}
|
image: ${IMAGE}-cypress:ci-${BUILD_NUMBER}
|
||||||
build:
|
build:
|
||||||
context: ../
|
context: ../test/
|
||||||
dockerfile: test/cypress/Dockerfile
|
dockerfile: cypress/Dockerfile
|
||||||
environment:
|
environment:
|
||||||
CYPRESS_baseUrl: "http://fullstack-sqlite:81"
|
CYPRESS_baseUrl: "http://fullstack-sqlite:81"
|
||||||
volumes:
|
volumes:
|
||||||
|
@ -11,21 +11,33 @@ services:
|
|||||||
- 3080:80
|
- 3080:80
|
||||||
- 3081:81
|
- 3081:81
|
||||||
- 3443:443
|
- 3443:443
|
||||||
|
networks:
|
||||||
|
- nginx_proxy_manager
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=development
|
NODE_ENV: "development"
|
||||||
- FORCE_COLOR=1
|
FORCE_COLOR: 1
|
||||||
- DEVELOPMENT=true
|
DEVELOPMENT: "true"
|
||||||
#- DISABLE_IPV6=true
|
DB_MYSQL_HOST: "db"
|
||||||
|
DB_MYSQL_PORT: 3306
|
||||||
|
DB_MYSQL_USER: "npm"
|
||||||
|
DB_MYSQL_PASSWORD: "npm"
|
||||||
|
DB_MYSQL_NAME: "npm"
|
||||||
|
# DB_SQLITE_FILE: "/data/database.sqlite"
|
||||||
|
# DISABLE_IPV6: "true"
|
||||||
volumes:
|
volumes:
|
||||||
- npm_data:/data
|
- npm_data:/data
|
||||||
- le_data:/etc/letsencrypt
|
- le_data:/etc/letsencrypt
|
||||||
- ..:/app
|
- ../backend:/app
|
||||||
|
- ../frontend:/app/frontend
|
||||||
|
- ../global:/app/global
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
working_dir: /app
|
working_dir: /app
|
||||||
|
|
||||||
db:
|
db:
|
||||||
image: jc21/mariadb-aria
|
image: jc21/mariadb-aria
|
||||||
|
networks:
|
||||||
|
- nginx_proxy_manager
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: "npm"
|
MYSQL_ROOT_PASSWORD: "npm"
|
||||||
MYSQL_DATABASE: "npm"
|
MYSQL_DATABASE: "npm"
|
||||||
@ -38,6 +50,8 @@ services:
|
|||||||
image: 'swaggerapi/swagger-ui:latest'
|
image: 'swaggerapi/swagger-ui:latest'
|
||||||
ports:
|
ports:
|
||||||
- 3001:80
|
- 3001:80
|
||||||
|
networks:
|
||||||
|
- nginx_proxy_manager
|
||||||
environment:
|
environment:
|
||||||
URL: "http://127.0.0.1:3081/api/schema"
|
URL: "http://127.0.0.1:3081/api/schema"
|
||||||
PORT: '80'
|
PORT: '80'
|
||||||
@ -48,3 +62,6 @@ volumes:
|
|||||||
npm_data:
|
npm_data:
|
||||||
le_data:
|
le_data:
|
||||||
db_data:
|
db_data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
nginx_proxy_manager:
|
||||||
|
1
docker/rootfs/etc/cont-init.d/.gitignore
vendored
1
docker/rootfs/etc/cont-init.d/.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
*
|
*
|
||||||
!.gitignore
|
!.gitignore
|
||||||
|
!*.sh
|
||||||
|
29
docker/rootfs/etc/cont-init.d/01_s6-secret-init.sh
Normal file
29
docker/rootfs/etc/cont-init.d/01_s6-secret-init.sh
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/with-contenv bash
|
||||||
|
# ref: https://github.com/linuxserver/docker-baseimage-alpine/blob/master/root/etc/cont-init.d/01-envfile
|
||||||
|
|
||||||
|
# in s6, environmental variables are written as text files for s6 to monitor
|
||||||
|
# seach through full-path filenames for files ending in "__FILE"
|
||||||
|
for FILENAME in $(find /var/run/s6/container_environment/ | grep "__FILE$"); do
|
||||||
|
echo "[secret-init] Evaluating ${FILENAME##*/} ..."
|
||||||
|
|
||||||
|
# set SECRETFILE to the contents of the full-path textfile
|
||||||
|
SECRETFILE=$(cat ${FILENAME})
|
||||||
|
# SECRETFILE=${FILENAME}
|
||||||
|
# echo "[secret-init] Set SECRETFILE to ${SECRETFILE}" # DEBUG - rm for prod!
|
||||||
|
|
||||||
|
# if SECRETFILE exists / is not null
|
||||||
|
if [[ -f ${SECRETFILE} ]]; then
|
||||||
|
# strip the appended "__FILE" from environmental variable name ...
|
||||||
|
STRIPFILE=$(echo ${FILENAME} | sed "s/__FILE//g")
|
||||||
|
# echo "[secret-init] Set STRIPFILE to ${STRIPFILE}" # DEBUG - rm for prod!
|
||||||
|
|
||||||
|
# ... and set value to contents of secretfile
|
||||||
|
# since s6 uses text files, this is effectively "export ..."
|
||||||
|
printf $(cat ${SECRETFILE}) > ${STRIPFILE}
|
||||||
|
# echo "[secret-init] Set ${STRIPFILE##*/} to $(cat ${STRIPFILE})" # DEBUG - rm for prod!"
|
||||||
|
echo "[secret-init] Success! ${STRIPFILE##*/} set from ${FILENAME##*/}"
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "[secret-init] cannot find secret in ${FILENAME}"
|
||||||
|
fi
|
||||||
|
done
|
@ -17,6 +17,9 @@ server {
|
|||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_set_header X-Forwarded-For $remote_addr;
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
proxy_pass http://127.0.0.1:3000/;
|
proxy_pass http://127.0.0.1:3000/;
|
||||||
|
|
||||||
|
proxy_read_timeout 15m;
|
||||||
|
proxy_send_timeout 15m;
|
||||||
}
|
}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
|
@ -1,196 +1,2 @@
|
|||||||
|
# This should be left blank is it is populated programatically
|
||||||
set_real_ip_from 144.220.0.0/16;
|
# by the application backend.
|
||||||
|
|
||||||
set_real_ip_from 52.124.128.0/17;
|
|
||||||
|
|
||||||
set_real_ip_from 54.230.0.0/16;
|
|
||||||
|
|
||||||
set_real_ip_from 54.239.128.0/18;
|
|
||||||
|
|
||||||
set_real_ip_from 52.82.128.0/19;
|
|
||||||
|
|
||||||
set_real_ip_from 99.84.0.0/16;
|
|
||||||
|
|
||||||
set_real_ip_from 204.246.172.0/24;
|
|
||||||
|
|
||||||
set_real_ip_from 205.251.192.0/19;
|
|
||||||
|
|
||||||
set_real_ip_from 54.239.192.0/19;
|
|
||||||
|
|
||||||
set_real_ip_from 70.132.0.0/18;
|
|
||||||
|
|
||||||
set_real_ip_from 13.32.0.0/15;
|
|
||||||
|
|
||||||
set_real_ip_from 13.224.0.0/14;
|
|
||||||
|
|
||||||
set_real_ip_from 13.35.0.0/16;
|
|
||||||
|
|
||||||
set_real_ip_from 204.246.164.0/22;
|
|
||||||
|
|
||||||
set_real_ip_from 204.246.168.0/22;
|
|
||||||
|
|
||||||
set_real_ip_from 71.152.0.0/17;
|
|
||||||
|
|
||||||
set_real_ip_from 216.137.32.0/19;
|
|
||||||
|
|
||||||
set_real_ip_from 205.251.249.0/24;
|
|
||||||
|
|
||||||
set_real_ip_from 99.86.0.0/16;
|
|
||||||
|
|
||||||
set_real_ip_from 52.46.0.0/18;
|
|
||||||
|
|
||||||
set_real_ip_from 52.84.0.0/15;
|
|
||||||
|
|
||||||
set_real_ip_from 204.246.173.0/24;
|
|
||||||
|
|
||||||
set_real_ip_from 130.176.0.0/16;
|
|
||||||
|
|
||||||
set_real_ip_from 64.252.64.0/18;
|
|
||||||
|
|
||||||
set_real_ip_from 204.246.174.0/23;
|
|
||||||
|
|
||||||
set_real_ip_from 64.252.128.0/18;
|
|
||||||
|
|
||||||
set_real_ip_from 205.251.254.0/24;
|
|
||||||
|
|
||||||
set_real_ip_from 143.204.0.0/16;
|
|
||||||
|
|
||||||
set_real_ip_from 205.251.252.0/23;
|
|
||||||
|
|
||||||
set_real_ip_from 204.246.176.0/20;
|
|
||||||
|
|
||||||
set_real_ip_from 13.249.0.0/16;
|
|
||||||
|
|
||||||
set_real_ip_from 54.240.128.0/18;
|
|
||||||
|
|
||||||
set_real_ip_from 205.251.250.0/23;
|
|
||||||
|
|
||||||
set_real_ip_from 52.222.128.0/17;
|
|
||||||
|
|
||||||
set_real_ip_from 54.182.0.0/16;
|
|
||||||
|
|
||||||
set_real_ip_from 54.192.0.0/16;
|
|
||||||
|
|
||||||
set_real_ip_from 13.124.199.0/24;
|
|
||||||
|
|
||||||
set_real_ip_from 34.226.14.0/24;
|
|
||||||
|
|
||||||
set_real_ip_from 52.15.127.128/26;
|
|
||||||
|
|
||||||
set_real_ip_from 35.158.136.0/24;
|
|
||||||
|
|
||||||
set_real_ip_from 52.57.254.0/24;
|
|
||||||
|
|
||||||
set_real_ip_from 18.216.170.128/25;
|
|
||||||
|
|
||||||
set_real_ip_from 13.52.204.0/23;
|
|
||||||
|
|
||||||
set_real_ip_from 13.54.63.128/26;
|
|
||||||
|
|
||||||
set_real_ip_from 13.59.250.0/26;
|
|
||||||
|
|
||||||
set_real_ip_from 13.210.67.128/26;
|
|
||||||
|
|
||||||
set_real_ip_from 35.167.191.128/26;
|
|
||||||
|
|
||||||
set_real_ip_from 52.47.139.0/24;
|
|
||||||
|
|
||||||
set_real_ip_from 52.199.127.192/26;
|
|
||||||
|
|
||||||
set_real_ip_from 52.212.248.0/26;
|
|
||||||
|
|
||||||
set_real_ip_from 52.66.194.128/26;
|
|
||||||
|
|
||||||
set_real_ip_from 13.113.203.0/24;
|
|
||||||
|
|
||||||
set_real_ip_from 99.79.168.0/23;
|
|
||||||
|
|
||||||
set_real_ip_from 34.195.252.0/24;
|
|
||||||
|
|
||||||
set_real_ip_from 35.162.63.192/26;
|
|
||||||
|
|
||||||
set_real_ip_from 34.223.12.224/27;
|
|
||||||
|
|
||||||
set_real_ip_from 52.56.127.0/25;
|
|
||||||
|
|
||||||
set_real_ip_from 34.223.80.192/26;
|
|
||||||
|
|
||||||
set_real_ip_from 13.228.69.0/24;
|
|
||||||
|
|
||||||
set_real_ip_from 34.216.51.0/25;
|
|
||||||
|
|
||||||
set_real_ip_from 3.231.2.0/25;
|
|
||||||
|
|
||||||
set_real_ip_from 54.233.255.128/26;
|
|
||||||
|
|
||||||
set_real_ip_from 18.200.212.0/23;
|
|
||||||
|
|
||||||
set_real_ip_from 52.52.191.128/26;
|
|
||||||
|
|
||||||
set_real_ip_from 3.234.232.224/27;
|
|
||||||
|
|
||||||
set_real_ip_from 52.78.247.128/26;
|
|
||||||
|
|
||||||
set_real_ip_from 52.220.191.0/26;
|
|
||||||
|
|
||||||
set_real_ip_from 34.232.163.208/29;
|
|
||||||
|
|
||||||
set_real_ip_from 2600:9000:eee::/48;
|
|
||||||
|
|
||||||
set_real_ip_from 2600:9000:4000::/36;
|
|
||||||
|
|
||||||
set_real_ip_from 2600:9000:3000::/36;
|
|
||||||
|
|
||||||
set_real_ip_from 2600:9000:f000::/36;
|
|
||||||
|
|
||||||
set_real_ip_from 2600:9000:fff::/48;
|
|
||||||
|
|
||||||
set_real_ip_from 2600:9000:2000::/36;
|
|
||||||
|
|
||||||
set_real_ip_from 2600:9000:1000::/36;
|
|
||||||
|
|
||||||
set_real_ip_from 2600:9000:ddd::/48;
|
|
||||||
|
|
||||||
set_real_ip_from 2600:9000:5300::/40;
|
|
||||||
|
|
||||||
set_real_ip_from 173.245.48.0/20;
|
|
||||||
|
|
||||||
set_real_ip_from 103.21.244.0/22;
|
|
||||||
|
|
||||||
set_real_ip_from 103.22.200.0/22;
|
|
||||||
|
|
||||||
set_real_ip_from 103.31.4.0/22;
|
|
||||||
|
|
||||||
set_real_ip_from 141.101.64.0/18;
|
|
||||||
|
|
||||||
set_real_ip_from 108.162.192.0/18;
|
|
||||||
|
|
||||||
set_real_ip_from 190.93.240.0/20;
|
|
||||||
|
|
||||||
set_real_ip_from 188.114.96.0/20;
|
|
||||||
|
|
||||||
set_real_ip_from 197.234.240.0/22;
|
|
||||||
|
|
||||||
set_real_ip_from 198.41.128.0/17;
|
|
||||||
|
|
||||||
set_real_ip_from 162.158.0.0/15;
|
|
||||||
|
|
||||||
set_real_ip_from 104.16.0.0/12;
|
|
||||||
|
|
||||||
set_real_ip_from 172.64.0.0/13;
|
|
||||||
|
|
||||||
set_real_ip_from 131.0.72.0/22;
|
|
||||||
|
|
||||||
set_real_ip_from 2400:cb00::/32;
|
|
||||||
|
|
||||||
set_real_ip_from 2606:4700::/32;
|
|
||||||
|
|
||||||
set_real_ip_from 2803:f800::/32;
|
|
||||||
|
|
||||||
set_real_ip_from 2405:b500::/32;
|
|
||||||
|
|
||||||
set_real_ip_from 2405:8100::/32;
|
|
||||||
|
|
||||||
set_real_ip_from 2a06:98c0::/29;
|
|
||||||
|
|
||||||
set_real_ip_from 2c0f:f248::/32;
|
|
||||||
|
@ -3,4 +3,6 @@ proxy_set_header Host $host;
|
|||||||
proxy_set_header X-Forwarded-Scheme $scheme;
|
proxy_set_header X-Forwarded-Scheme $scheme;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_set_header X-Forwarded-For $remote_addr;
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_pass $forward_scheme://$server:$port;
|
proxy_pass $forward_scheme://$server:$port;
|
||||||
|
|
||||||
|
@ -18,6 +18,9 @@ server {
|
|||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_set_header X-Forwarded-For $remote_addr;
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
proxy_pass http://127.0.0.1:3000/;
|
proxy_pass http://127.0.0.1:3000/;
|
||||||
|
|
||||||
|
proxy_read_timeout 15m;
|
||||||
|
proxy_send_timeout 15m;
|
||||||
}
|
}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
|
@ -66,9 +66,12 @@ http {
|
|||||||
# 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-Forwarded-For;
|
real_ip_header X-Real-IP;
|
||||||
real_ip_recursive on;
|
real_ip_recursive on;
|
||||||
|
|
||||||
|
# Custom
|
||||||
|
include /data/nginx/custom/http_top[.]conf;
|
||||||
|
|
||||||
# Files generated by NPM
|
# Files generated by NPM
|
||||||
include /etc/nginx/conf.d/*.conf;
|
include /etc/nginx/conf.d/*.conf;
|
||||||
include /data/nginx/default_host/*.conf;
|
include /data/nginx/default_host/*.conf;
|
||||||
@ -84,6 +87,9 @@ http {
|
|||||||
stream {
|
stream {
|
||||||
# Files generated by NPM
|
# Files generated by NPM
|
||||||
include /data/nginx/stream/*.conf;
|
include /data/nginx/stream/*.conf;
|
||||||
|
|
||||||
|
# Custom
|
||||||
|
include /data/nginx/custom/stream[.]conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Custom
|
# Custom
|
||||||
|
@ -5,7 +5,7 @@ mkdir -p /data/letsencrypt-acme-challenge
|
|||||||
cd /app || echo
|
cd /app || echo
|
||||||
|
|
||||||
if [ "$DEVELOPMENT" == "true" ]; then
|
if [ "$DEVELOPMENT" == "true" ]; then
|
||||||
cd /app/backend || exit 1
|
cd /app || exit 1
|
||||||
yarn install
|
yarn install
|
||||||
node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js
|
node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js
|
||||||
else
|
else
|
||||||
|
@ -16,5 +16,7 @@ alias h='cd ~;clear;'
|
|||||||
|
|
||||||
echo -e -n '\E[1;34m'
|
echo -e -n '\E[1;34m'
|
||||||
figlet -w 120 "NginxProxyManager"
|
figlet -w 120 "NginxProxyManager"
|
||||||
echo -e "\E[1;36mVersion \E[1;32m${NPM_BUILD_VERSION:-2.0.0-dev} (${NPM_BUILD_COMMIT:-dev}) ${NPM_BUILD_DATE:-0000-00-00}\E[1;36m, OpenResty \E[1;32m${OPENRESTY_VERSION:-unknown}\E[1;36m, Alpine \E[1;32m${VERSION_ID:-unknown}\E[1;36m, Kernel \E[1;32m$(uname -r)\E[0m"
|
echo -e "\E[1;36mVersion \E[1;32m${NPM_BUILD_VERSION:-2.0.0-dev} (${NPM_BUILD_COMMIT:-dev}) ${NPM_BUILD_DATE:-0000-00-00}\E[1;36m, OpenResty \E[1;32m${OPENRESTY_VERSION:-unknown}\E[1;36m, ${ID:-debian} \E[1;32m${VERSION:-unknown}\E[1;36m, Certbot \E[1;32m$(certbot --version)\E[0m"
|
||||||
echo
|
echo -e -n '\E[1;34m'
|
||||||
|
cat /built-for-arch
|
||||||
|
echo -e '\E[0m'
|
||||||
|
@ -47,6 +47,7 @@ module.exports = {
|
|||||||
["/screenshots/", "Screenshots"],
|
["/screenshots/", "Screenshots"],
|
||||||
["/setup/", "Setup Instructions"],
|
["/setup/", "Setup Instructions"],
|
||||||
["/advanced-config/", "Advanced Configuration"],
|
["/advanced-config/", "Advanced Configuration"],
|
||||||
|
["/upgrading/", "Upgrading"],
|
||||||
["/faq/", "Frequently Asked Questions"],
|
["/faq/", "Frequently Asked Questions"],
|
||||||
["/third-party/", "Third Party"]
|
["/third-party/", "Third Party"]
|
||||||
]
|
]
|
||||||
|
@ -45,21 +45,7 @@ footer: MIT Licensed | Copyright © 2016-present jc21.com
|
|||||||
- [Docker Install documentation](https://docs.docker.com/install/)
|
- [Docker Install documentation](https://docs.docker.com/install/)
|
||||||
- [Docker-Compose Install documentation](https://docs.docker.com/compose/install/)
|
- [Docker-Compose Install documentation](https://docs.docker.com/compose/install/)
|
||||||
|
|
||||||
2. Create a config file for example
|
2. Create a docker-compose.yml file similar to this:
|
||||||
```json
|
|
||||||
{
|
|
||||||
"database": {
|
|
||||||
"engine": "mysql",
|
|
||||||
"host": "db",
|
|
||||||
"name": "npm",
|
|
||||||
"user": "npm",
|
|
||||||
"password": "npm",
|
|
||||||
"port": 3306
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Create a docker-compose.yml file similar to this:
|
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
version: '3'
|
version: '3'
|
||||||
@ -70,12 +56,17 @@ services:
|
|||||||
- '80:80'
|
- '80:80'
|
||||||
- '81:81'
|
- '81:81'
|
||||||
- '443:443'
|
- '443:443'
|
||||||
|
environment:
|
||||||
|
DB_MYSQL_HOST: "db"
|
||||||
|
DB_MYSQL_PORT: 3306
|
||||||
|
DB_MYSQL_USER: "npm"
|
||||||
|
DB_MYSQL_PASSWORD: "npm"
|
||||||
|
DB_MYSQL_NAME: "npm"
|
||||||
volumes:
|
volumes:
|
||||||
- ./config.json:/app/config/production.json
|
|
||||||
- ./data:/data
|
- ./data:/data
|
||||||
- ./letsencrypt:/etc/letsencrypt
|
- ./letsencrypt:/etc/letsencrypt
|
||||||
db:
|
db:
|
||||||
image: 'jc21/mariadb-aria:10.4'
|
image: 'jc21/mariadb-aria:latest'
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: 'npm'
|
MYSQL_ROOT_PASSWORD: 'npm'
|
||||||
MYSQL_DATABASE: 'npm'
|
MYSQL_DATABASE: 'npm'
|
||||||
@ -85,13 +76,13 @@ services:
|
|||||||
- ./data/mysql:/var/lib/mysql
|
- ./data/mysql:/var/lib/mysql
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Bring up your stack
|
3. Bring up your stack
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
5. Log in to the Admin UI
|
4. Log in to the Admin UI
|
||||||
|
|
||||||
When your docker container is running, connect to it on port `81` for the admin interface.
|
When your docker container is running, connect to it on port `81` for the admin interface.
|
||||||
Sometimes this can take a little bit because of the entropy of keys.
|
Sometimes this can take a little bit because of the entropy of keys.
|
||||||
@ -106,3 +97,15 @@ Password: changeme
|
|||||||
```
|
```
|
||||||
|
|
||||||
Immediately after logging in with this default user you will be asked to modify your details and change your password.
|
Immediately after logging in with this default user you will be asked to modify your details and change your password.
|
||||||
|
|
||||||
|
5. Upgrading to new versions
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose pull
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
This project will automatically update any databases or other requirements so you don't have to follow
|
||||||
|
any crazy instructions. These steps above will pull the latest updates and recreate the docker
|
||||||
|
containers.
|
||||||
|
|
||||||
|
@ -1,5 +1,119 @@
|
|||||||
# Advanced Configuration
|
# Advanced Configuration
|
||||||
|
|
||||||
|
## Best Practice: Use a docker network
|
||||||
|
|
||||||
|
For those who have a few of their upstream services running in docker on the same docker
|
||||||
|
host as NPM, here's a trick to secure things a bit better. By creating a custom docker network,
|
||||||
|
you don't need to publish ports for your upstream services to all of the docker host's interfaces.
|
||||||
|
|
||||||
|
Create a network, ie "scoobydoo":
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker network create scoobydoo
|
||||||
|
```
|
||||||
|
|
||||||
|
Then add the following to the `docker-compose.yml` file for both NPM and any other
|
||||||
|
services running on this docker host:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
external:
|
||||||
|
name: scoobydoo
|
||||||
|
```
|
||||||
|
|
||||||
|
Let's look at a Portainer example:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
|
||||||
|
portainer:
|
||||||
|
image: portainer/portainer
|
||||||
|
privileged: true
|
||||||
|
volumes:
|
||||||
|
- './data:/data'
|
||||||
|
- '/var/run/docker.sock:/var/run/docker.sock'
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
external:
|
||||||
|
name: scoobydoo
|
||||||
|
```
|
||||||
|
|
||||||
|
Now in the NPM UI you can create a proxy host with `portainer` as the hostname,
|
||||||
|
and port `9000` as the port. Even though this port isn't listed in the docker-compose
|
||||||
|
file, it's "exposed" by the portainer docker image for you and not available on
|
||||||
|
the docker host outside of this docker network. The service name is used as the
|
||||||
|
hostname, so make sure your service names are unique when using the same network.
|
||||||
|
|
||||||
|
## Docker Secrets
|
||||||
|
|
||||||
|
This image supports the use of Docker secrets to import from file and keep sensitive usernames or passwords from being passed or preserved in plaintext.
|
||||||
|
|
||||||
|
You can set any environment variable from a file by appending `__FILE` (double-underscore FILE) to the environmental variable name.
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: "3.7"
|
||||||
|
|
||||||
|
secrets:
|
||||||
|
# Secrets are single-line text files where the sole content is the secret
|
||||||
|
# Paths in this example assume that secrets are kept in local folder called ".secrets"
|
||||||
|
DB_ROOT_PWD:
|
||||||
|
file: .secrets/db_root_pwd.txt
|
||||||
|
MYSQL_PWD:
|
||||||
|
file: .secrets/mysql_pwd.txt
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: 'jc21/nginx-proxy-manager:latest'
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
# Public HTTP Port:
|
||||||
|
- '80:80'
|
||||||
|
# Public HTTPS Port:
|
||||||
|
- '443:443'
|
||||||
|
# Admin Web Port:
|
||||||
|
- '81:81'
|
||||||
|
environment:
|
||||||
|
# These are the settings to access your db
|
||||||
|
DB_MYSQL_HOST: "db"
|
||||||
|
DB_MYSQL_PORT: 3306
|
||||||
|
DB_MYSQL_USER: "npm"
|
||||||
|
# DB_MYSQL_PASSWORD: "npm" # use secret instead
|
||||||
|
DB_MYSQL_PASSWORD__FILE: /run/secrets/MYSQL_PWD
|
||||||
|
DB_MYSQL_NAME: "npm"
|
||||||
|
# If you would rather use Sqlite uncomment this
|
||||||
|
# and remove all DB_MYSQL_* lines above
|
||||||
|
# DB_SQLITE_FILE: "/data/database.sqlite"
|
||||||
|
# Uncomment this if IPv6 is not enabled on your host
|
||||||
|
# DISABLE_IPV6: 'true'
|
||||||
|
volumes:
|
||||||
|
- ./data:/data
|
||||||
|
- ./letsencrypt:/etc/letsencrypt
|
||||||
|
secrets:
|
||||||
|
- MYSQL_PWD
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
db:
|
||||||
|
image: jc21/mariadb-aria
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
# MYSQL_ROOT_PASSWORD: "npm" # use secret instead
|
||||||
|
MYSQL_ROOT_PASSWORD__FILE: /run/secrets/DB_ROOT_PWD
|
||||||
|
MYSQL_DATABASE: "npm"
|
||||||
|
MYSQL_USER: "npm"
|
||||||
|
# MYSQL_PASSWORD: "npm" # use secret instead
|
||||||
|
MYSQL_PASSWORD__FILE: /run/secrets/MYSQL_PWD
|
||||||
|
volumes:
|
||||||
|
- ./data/mysql:/var/lib/mysql
|
||||||
|
secrets:
|
||||||
|
- DB_ROOT_PWD
|
||||||
|
- MYSQL_PWD
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Disabling IPv6
|
## Disabling IPv6
|
||||||
|
|
||||||
On some docker hosts IPv6 may not be enabled. In these cases, the following message may be seen in the log:
|
On some docker hosts IPv6 may not be enabled. In these cases, the following message may be seen in the log:
|
||||||
@ -23,7 +137,9 @@ NPM has the ability to include different custom configuration snippets in differ
|
|||||||
You can add your custom configuration snippet files at `/data/nginx/custom` as follow:
|
You can add your custom configuration snippet files at `/data/nginx/custom` as follow:
|
||||||
|
|
||||||
- `/data/nginx/custom/root.conf`: Included at the very end of nginx.conf
|
- `/data/nginx/custom/root.conf`: Included at the very end of nginx.conf
|
||||||
|
- `/data/nginx/custom/http_top.conf`: Included at the top of the main http block
|
||||||
- `/data/nginx/custom/http.conf`: Included at the end of the main http block
|
- `/data/nginx/custom/http.conf`: Included at the end of the main http block
|
||||||
|
- `/data/nginx/custom/stream.conf`: Included at the end of the main stream block
|
||||||
- `/data/nginx/custom/server_proxy.conf`: Included at the end of every proxy server block
|
- `/data/nginx/custom/server_proxy.conf`: Included at the end of every proxy server block
|
||||||
- `/data/nginx/custom/server_redirect.conf`: Included at the end of every redirection server block
|
- `/data/nginx/custom/server_redirect.conf`: Included at the end of every redirection server block
|
||||||
- `/data/nginx/custom/server_stream.conf`: Included at the end of every stream server block
|
- `/data/nginx/custom/server_stream.conf`: Included at the end of every stream server block
|
||||||
|
@ -14,3 +14,10 @@ of dependencies.
|
|||||||
Yes! The docker image is multi-arch and is built for a variety of architectures. If yours is
|
Yes! The docker image is multi-arch and is built for a variety of architectures. If yours is
|
||||||
[not listed](https://hub.docker.com/r/jc21/nginx-proxy-manager/tags) please open a
|
[not listed](https://hub.docker.com/r/jc21/nginx-proxy-manager/tags) please open a
|
||||||
[GitHub issue](https://github.com/jc21/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=).
|
[GitHub issue](https://github.com/jc21/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=).
|
||||||
|
|
||||||
|
## I can't get my service to proxy properly?
|
||||||
|
|
||||||
|
Your best bet is to ask the [Reddit community for support](https://www.reddit.com/r/nginxproxymanager/). There's safety in numbers.
|
||||||
|
|
||||||
|
Gitter is best left for anyone contributing to the project to ask for help about internals, code reviews etc.
|
||||||
|
|
||||||
|
@ -434,7 +434,7 @@
|
|||||||
"neo-async": "^2.6.2",
|
"neo-async": "^2.6.2",
|
||||||
"nice-try": "^2.0.1",
|
"nice-try": "^2.0.1",
|
||||||
"no-case": "^3.0.3",
|
"no-case": "^3.0.3",
|
||||||
"node-forge": "^0.9.1",
|
"node-forge": "^0.10.0",
|
||||||
"node-libs-browser": "^2.2.1",
|
"node-libs-browser": "^2.2.1",
|
||||||
"node-releases": "^1.1.60",
|
"node-releases": "^1.1.60",
|
||||||
"nopt": "^4.0.3",
|
"nopt": "^4.0.3",
|
||||||
|
@ -1,50 +1,5 @@
|
|||||||
# Full Setup Instructions
|
# Full Setup Instructions
|
||||||
|
|
||||||
### Configuration File
|
|
||||||
|
|
||||||
**The configuration file needs to be provided by you!**
|
|
||||||
|
|
||||||
Don't worry, this is easy to do.
|
|
||||||
|
|
||||||
The app requires a configuration file to let it know what database you're using. By default, this file is called `config.json`
|
|
||||||
|
|
||||||
Here's an example configuration for `mysql` (or mariadb) that is compatible with the docker-compose example below:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"database": {
|
|
||||||
"engine": "mysql",
|
|
||||||
"host": "db",
|
|
||||||
"name": "npm",
|
|
||||||
"user": "npm",
|
|
||||||
"password": "npm",
|
|
||||||
"port": 3306
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Alternatively if you would like to use a Sqlite database file:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"database": {
|
|
||||||
"engine": "knex-native",
|
|
||||||
"knex": {
|
|
||||||
"client": "sqlite3",
|
|
||||||
"connection": {
|
|
||||||
"filename": "/data/database.sqlite"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Once you've created your configuration file it's easy to mount it in the docker container.
|
|
||||||
|
|
||||||
**Note:** After the first run of the application, the config file will be altered to include generated encryption keys unique to your installation. These keys
|
|
||||||
affect the login and session management of the application. If these keys change for any reason, all users will be logged out.
|
|
||||||
|
|
||||||
|
|
||||||
### MySQL Database
|
### MySQL 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. You can also use MariaDB. Here are the minimum supported versions:
|
||||||
@ -61,7 +16,6 @@ When using a `mariadb` database, the NPM configuration file should still use the
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
|
||||||
### Running the App
|
### Running the App
|
||||||
|
|
||||||
Via `docker-compose`:
|
Via `docker-compose`:
|
||||||
@ -70,7 +24,7 @@ Via `docker-compose`:
|
|||||||
version: "3"
|
version: "3"
|
||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
image: jc21/nginx-proxy-manager:2
|
image: 'jc21/nginx-proxy-manager:latest'
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
# Public HTTP Port:
|
# Public HTTP Port:
|
||||||
@ -79,18 +33,27 @@ services:
|
|||||||
- '443:443'
|
- '443:443'
|
||||||
# Admin Web Port:
|
# Admin Web Port:
|
||||||
- '81:81'
|
- '81:81'
|
||||||
|
# Add any other Stream port you want to expose
|
||||||
|
# - '21:21' # FTP
|
||||||
environment:
|
environment:
|
||||||
|
# These are the settings to access your db
|
||||||
|
DB_MYSQL_HOST: "db"
|
||||||
|
DB_MYSQL_PORT: 3306
|
||||||
|
DB_MYSQL_USER: "npm"
|
||||||
|
DB_MYSQL_PASSWORD: "npm"
|
||||||
|
DB_MYSQL_NAME: "npm"
|
||||||
|
# If you would rather use Sqlite uncomment this
|
||||||
|
# and remove all DB_MYSQL_* lines above
|
||||||
|
# DB_SQLITE_FILE: "/data/database.sqlite"
|
||||||
# Uncomment this if IPv6 is not enabled on your host
|
# Uncomment this if IPv6 is not enabled on your host
|
||||||
# DISABLE_IPV6: 'true'
|
# DISABLE_IPV6: 'true'
|
||||||
volumes:
|
volumes:
|
||||||
# Make sure this config.json file exists as per instructions above:
|
|
||||||
- ./config.json:/app/config/production.json
|
|
||||||
- ./data:/data
|
- ./data:/data
|
||||||
- ./letsencrypt:/etc/letsencrypt
|
- ./letsencrypt:/etc/letsencrypt
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
db:
|
db:
|
||||||
image: jc21/mariadb-aria:10.4
|
image: 'jc21/mariadb-aria:latest'
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: 'npm'
|
MYSQL_ROOT_PASSWORD: 'npm'
|
||||||
@ -101,14 +64,14 @@ services:
|
|||||||
- ./data/mysql:/var/lib/mysql
|
- ./data/mysql:/var/lib/mysql
|
||||||
```
|
```
|
||||||
|
|
||||||
|
_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._
|
||||||
|
|
||||||
Then:
|
Then:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
The config file (config.json) must be present in this directory.
|
|
||||||
|
|
||||||
### Running on Raspberry PI / ARM devices
|
### Running on Raspberry PI / ARM devices
|
||||||
|
|
||||||
The docker images support the following architectures:
|
The docker images support the following architectures:
|
||||||
@ -146,3 +109,49 @@ Password: changeme
|
|||||||
```
|
```
|
||||||
|
|
||||||
Immediately after logging in with this default user you will be asked to modify your details and change your password.
|
Immediately after logging in with this default user you will be asked to modify your details and change your password.
|
||||||
|
|
||||||
|
### Configuration File
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
|
||||||
|
This section is meant for advanced users
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
If you would like more control over the database settings you can define a custom config JSON file.
|
||||||
|
|
||||||
|
|
||||||
|
Here's an example for `sqlite` configuration as it is generated from the environment variables:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"database": {
|
||||||
|
"engine": "knex-native",
|
||||||
|
"knex": {
|
||||||
|
"client": "sqlite3",
|
||||||
|
"connection": {
|
||||||
|
"filename": "/data/database.sqlite"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can modify the `knex` object with your custom configuration, but note that not all knex clients might be installed in the image.
|
||||||
|
|
||||||
|
Once you've created your configuration file you can mount it to `/app/config/production.json` inside you container using:
|
||||||
|
|
||||||
|
```
|
||||||
|
[...]
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: 'jc21/nginx-proxy-manager:latest'
|
||||||
|
[...]
|
||||||
|
volumes:
|
||||||
|
- ./config.json:/app/config/production.json
|
||||||
|
[...]
|
||||||
|
[...]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** After the first run of the application, the config file will be altered to include generated encryption keys unique to your installation.
|
||||||
|
These keys affect the login and session management of the application. If these keys change for any reason, all users will be logged out.
|
||||||
|
4
docs/third-party/README.md
vendored
4
docs/third-party/README.md
vendored
@ -7,6 +7,10 @@ Known integrations:
|
|||||||
|
|
||||||
- [HomeAssistant Hass.io plugin](https://github.com/hassio-addons/addon-nginx-proxy-manager)
|
- [HomeAssistant Hass.io plugin](https://github.com/hassio-addons/addon-nginx-proxy-manager)
|
||||||
- [UnRaid / Synology](https://github.com/jlesage/docker-nginx-proxy-manager)
|
- [UnRaid / Synology](https://github.com/jlesage/docker-nginx-proxy-manager)
|
||||||
|
- [Proxmox Scripts](https://github.com/ej52/proxmox-scripts/tree/main/lxc/nginx-proxy-manager)
|
||||||
|
- [nginxproxymanagerGraf](https://github.com/ma-karai/nginxproxymanagerGraf)
|
||||||
|
|
||||||
|
|
||||||
If you would like your integration of NPM listed, please open a
|
If you would like your integration of NPM listed, please open a
|
||||||
[Github issue](https://github.com/jc21/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=)
|
[Github issue](https://github.com/jc21/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=)
|
||||||
|
|
||||||
|
11
docs/upgrading/README.md
Normal file
11
docs/upgrading/README.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Upgrading
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose pull
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
This project will automatically update any databases or other requirements so you don't have to follow
|
||||||
|
any crazy instructions. These steps above will pull the latest updates and recreate the docker
|
||||||
|
containers.
|
||||||
|
|
@ -2000,10 +2000,10 @@ bluebird@^3.1.1, bluebird@^3.5.5, bluebird@^3.7.2:
|
|||||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
||||||
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
|
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
|
||||||
|
|
||||||
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0:
|
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9:
|
||||||
version "4.11.9"
|
version "4.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828"
|
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
|
||||||
integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==
|
integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
|
||||||
|
|
||||||
bn.js@^5.1.1, bn.js@^5.1.2:
|
bn.js@^5.1.1, bn.js@^5.1.2:
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
@ -3675,17 +3675,17 @@ electron-to-chromium@^1.3.488, electron-to-chromium@^1.3.522:
|
|||||||
integrity sha512-67V62Z4CFOiAtox+o+tosGfVk0QX4DJgH609tjT8QymbJZVAI/jWnAthnr8c5hnRNziIRwkc9EMQYejiVz3/9Q==
|
integrity sha512-67V62Z4CFOiAtox+o+tosGfVk0QX4DJgH609tjT8QymbJZVAI/jWnAthnr8c5hnRNziIRwkc9EMQYejiVz3/9Q==
|
||||||
|
|
||||||
elliptic@^6.5.3:
|
elliptic@^6.5.3:
|
||||||
version "6.5.3"
|
version "6.5.4"
|
||||||
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6"
|
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
|
||||||
integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==
|
integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
bn.js "^4.4.0"
|
bn.js "^4.11.9"
|
||||||
brorand "^1.0.1"
|
brorand "^1.1.0"
|
||||||
hash.js "^1.0.0"
|
hash.js "^1.0.0"
|
||||||
hmac-drbg "^1.0.0"
|
hmac-drbg "^1.0.1"
|
||||||
inherits "^2.0.1"
|
inherits "^2.0.4"
|
||||||
minimalistic-assert "^1.0.0"
|
minimalistic-assert "^1.0.1"
|
||||||
minimalistic-crypto-utils "^1.0.0"
|
minimalistic-crypto-utils "^1.0.1"
|
||||||
|
|
||||||
emoji-regex@^7.0.1:
|
emoji-regex@^7.0.1:
|
||||||
version "7.0.3"
|
version "7.0.3"
|
||||||
@ -4727,7 +4727,7 @@ hex-color-regex@^1.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
|
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
|
||||||
integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
|
integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
|
||||||
|
|
||||||
hmac-drbg@^1.0.0, hmac-drbg@^1.0.1:
|
hmac-drbg@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
||||||
integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
|
integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
|
||||||
@ -5125,9 +5125,9 @@ inherits@2.0.3:
|
|||||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||||
|
|
||||||
ini@^1.3.5, ini@~1.3.0:
|
ini@^1.3.5, ini@~1.3.0:
|
||||||
version "1.3.5"
|
version "1.3.8"
|
||||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
|
||||||
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
|
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
|
||||||
|
|
||||||
internal-ip@^4.3.0:
|
internal-ip@^4.3.0:
|
||||||
version "4.3.0"
|
version "4.3.0"
|
||||||
@ -5524,9 +5524,9 @@ is-svg@^3.0.0:
|
|||||||
html-comment-regex "^1.1.0"
|
html-comment-regex "^1.1.0"
|
||||||
|
|
||||||
is-svg@^4.2.1:
|
is-svg@^4.2.1:
|
||||||
version "4.2.1"
|
version "4.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-4.2.1.tgz#095b496e345fec9211c2a7d5d021003e040d6f81"
|
resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-4.2.2.tgz#a4ea0f3f78dada7085db88f1e85b6f845626cfae"
|
||||||
integrity sha512-PHx3ANecKsKNl5y5+Jvt53Y4J7MfMpbNZkv384QNiswMKAWIbvcqbPz+sYbFKJI8Xv3be01GSFniPmoaP+Ai5A==
|
integrity sha512-JlA7Mc7mfWjdxxTkJ094oUK9amGD7gQaj5xA/NCY0vlVvZ1stmj4VX+bRuwOMN93IHRZ2ctpPH/0FO6DqvQ5Rw==
|
||||||
dependencies:
|
dependencies:
|
||||||
html-comment-regex "^1.1.2"
|
html-comment-regex "^1.1.2"
|
||||||
|
|
||||||
@ -5993,9 +5993,9 @@ lodash.uniq@^4.5.0:
|
|||||||
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
||||||
|
|
||||||
lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.3, lodash@^4.17.5:
|
lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.3, lodash@^4.17.5:
|
||||||
version "4.17.19"
|
version "4.17.21"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
|
|
||||||
loglevel@^1.6.8:
|
loglevel@^1.6.8:
|
||||||
version "1.6.8"
|
version "1.6.8"
|
||||||
@ -6354,7 +6354,7 @@ minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
|
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
|
||||||
integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
|
integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
|
||||||
|
|
||||||
minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
|
minimalistic-crypto-utils@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
|
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
|
||||||
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
|
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
|
||||||
@ -6584,10 +6584,10 @@ node-forge@0.9.0:
|
|||||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579"
|
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579"
|
||||||
integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==
|
integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==
|
||||||
|
|
||||||
node-forge@^0.9.1:
|
node-forge@^0.10.0:
|
||||||
version "0.9.1"
|
version "0.10.0"
|
||||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.1.tgz#775368e6846558ab6676858a4d8c6e8d16c677b5"
|
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
|
||||||
integrity sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ==
|
integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==
|
||||||
|
|
||||||
node-libs-browser@^2.2.1:
|
node-libs-browser@^2.2.1:
|
||||||
version "2.2.1"
|
version "2.2.1"
|
||||||
@ -7679,9 +7679,9 @@ pretty-time@^1.1.0:
|
|||||||
integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==
|
integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==
|
||||||
|
|
||||||
prismjs@^1.13.0, prismjs@^1.20.0:
|
prismjs@^1.13.0, prismjs@^1.20.0:
|
||||||
version "1.21.0"
|
version "1.23.0"
|
||||||
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.21.0.tgz#36c086ec36b45319ec4218ee164c110f9fc015a3"
|
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.23.0.tgz#d3b3967f7d72440690497652a9d40ff046067f33"
|
||||||
integrity sha512-uGdSIu1nk3kej2iZsLyDoJ7e9bnPzIgY0naW/HdknGj61zScaprVEVGHrPoXqI+M9sP0NDnTK2jpkvmldpuqDw==
|
integrity sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
clipboard "^2.0.0"
|
clipboard "^2.0.0"
|
||||||
|
|
||||||
@ -8828,9 +8828,9 @@ ssri@^6.0.1:
|
|||||||
figgy-pudding "^3.5.1"
|
figgy-pudding "^3.5.1"
|
||||||
|
|
||||||
ssri@^8.0.0:
|
ssri@^8.0.0:
|
||||||
version "8.0.0"
|
version "8.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.0.tgz#79ca74e21f8ceaeddfcb4b90143c458b8d988808"
|
resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af"
|
||||||
integrity sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==
|
integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
minipass "^3.1.1"
|
minipass "^3.1.1"
|
||||||
|
|
||||||
@ -9632,9 +9632,9 @@ url-parse-lax@^3.0.0:
|
|||||||
prepend-http "^2.0.0"
|
prepend-http "^2.0.0"
|
||||||
|
|
||||||
url-parse@^1.4.3, url-parse@^1.4.7:
|
url-parse@^1.4.3, url-parse@^1.4.7:
|
||||||
version "1.4.7"
|
version "1.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278"
|
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.0.tgz#90aba6c902aeb2d80eac17b91131c27665d5d828"
|
||||||
integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==
|
integrity sha512-9iT6N4s93SMfzunOyDPe4vo4nLcSu1yq0IQK1gURmjm8tQNlM6loiuCRrKG1hHGXfB2EWd6H4cGi7tGdaygMFw==
|
||||||
dependencies:
|
dependencies:
|
||||||
querystringify "^2.1.1"
|
querystringify "^2.1.1"
|
||||||
requires-port "^1.0.0"
|
requires-port "^1.0.0"
|
||||||
@ -10264,9 +10264,9 @@ xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.1:
|
|||||||
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||||
|
|
||||||
y18n@^4.0.0:
|
y18n@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
|
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4"
|
||||||
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
|
integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==
|
||||||
|
|
||||||
yallist@^2.1.2:
|
yallist@^2.1.2:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
|
@ -53,7 +53,7 @@ function fetch(verb, path, data, options) {
|
|||||||
contentType: options.contentType || 'application/json; charset=UTF-8',
|
contentType: options.contentType || 'application/json; charset=UTF-8',
|
||||||
processData: options.processData || true,
|
processData: options.processData || true,
|
||||||
crossDomain: true,
|
crossDomain: true,
|
||||||
timeout: options.timeout ? options.timeout : 30000,
|
timeout: options.timeout ? options.timeout : 180000,
|
||||||
xhrFields: {
|
xhrFields: {
|
||||||
withCredentials: true
|
withCredentials: true
|
||||||
},
|
},
|
||||||
@ -139,7 +139,11 @@ function FileUpload(path, fd) {
|
|||||||
xhr.onreadystatechange = function () {
|
xhr.onreadystatechange = function () {
|
||||||
if (this.readyState === XMLHttpRequest.DONE) {
|
if (this.readyState === XMLHttpRequest.DONE) {
|
||||||
if (xhr.status !== 200 && xhr.status !== 201) {
|
if (xhr.status !== 200 && xhr.status !== 201) {
|
||||||
reject(new Error('Upload failed: ' + xhr.status));
|
try {
|
||||||
|
reject(new Error('Upload failed: ' + JSON.parse(xhr.responseText).error.message));
|
||||||
|
} catch (err) {
|
||||||
|
reject(new Error('Upload failed: ' + xhr.status));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
resolve(xhr.responseText);
|
resolve(xhr.responseText);
|
||||||
}
|
}
|
||||||
@ -587,7 +591,9 @@ module.exports = {
|
|||||||
* @param {Object} data
|
* @param {Object} data
|
||||||
*/
|
*/
|
||||||
create: function (data) {
|
create: function (data) {
|
||||||
return fetch('post', 'nginx/certificates', data);
|
|
||||||
|
const timeout = 180000 + (data && data.meta && data.meta.propagation_seconds ? Number(data.meta.propagation_seconds) * 1000 : 0);
|
||||||
|
return fetch('post', 'nginx/certificates', data, {timeout});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -630,8 +636,8 @@ module.exports = {
|
|||||||
* @param {Number} id
|
* @param {Number} id
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
renew: function (id) {
|
renew: function (id, timeout = 180000) {
|
||||||
return fetch('post', 'nginx/certificates/' + id + '/renew');
|
return fetch('post', 'nginx/certificates/' + id + '/renew', undefined, {timeout});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -31,11 +31,27 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-6 col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="custom-switch">
|
||||||
|
<input type="checkbox" class="custom-switch-input" name="pass_auth" value="1"<%- typeof pass_auth !== 'undefined' && pass_auth ? ' checked' : '' %>>
|
||||||
|
<span class="custom-switch-indicator"></span>
|
||||||
|
<span class="custom-switch-description"><%- i18n('access-lists', 'pass-auth') %></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Authorization -->
|
<!-- Authorization -->
|
||||||
<div class="tab-pane" id="auth">
|
<div class="tab-pane" id="auth">
|
||||||
|
<p>
|
||||||
|
Basic Authorization via
|
||||||
|
<a target="_blank" href="https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html">
|
||||||
|
Nginx HTTP Basic Authentication
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6 col-md-6">
|
<div class="col-sm-6 col-md-6">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@ -50,10 +66,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="items"><!-- items --></div>
|
<div class="items"><!-- items --></div>
|
||||||
|
<div class="btn-list justify-content-end">
|
||||||
|
<button type="button" class="btn btn-teal auth_add"><%- i18n('access-lists', 'auth-add') %></button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Access -->
|
<!-- Access -->
|
||||||
<div class="tab-pane" id="access">
|
<div class="tab-pane" id="access">
|
||||||
|
<p>
|
||||||
|
IP Address Whitelist/Blacklist via
|
||||||
|
<a target="_blank" href="https://nginx.org/en/docs/http/ngx_http_access_module.html">
|
||||||
|
Nginx HTTP Access
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
<div class="clients"><!-- clients --></div>
|
<div class="clients"><!-- clients --></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-3 col-md-3">
|
<div class="col-sm-3 col-md-3">
|
||||||
@ -68,6 +93,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-muted">Note that the <code>allow</code> and <code>deny</code> directives will be applied in the order they are defined.</div>
|
<div class="text-muted">Note that the <code>allow</code> and <code>deny</code> directives will be applied in the order they are defined.</div>
|
||||||
|
<div class="btn-list justify-content-end">
|
||||||
|
<button type="button" class="btn btn-teal access_add"><%- i18n('access-lists', 'access-add') %></button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -25,7 +25,9 @@ module.exports = Mn.View.extend({
|
|||||||
form: 'form',
|
form: 'form',
|
||||||
buttons: '.modal-footer button',
|
buttons: '.modal-footer button',
|
||||||
cancel: 'button.cancel',
|
cancel: 'button.cancel',
|
||||||
save: 'button.save'
|
save: 'button.save',
|
||||||
|
access_add: 'button.access_add',
|
||||||
|
auth_add: 'button.auth_add'
|
||||||
},
|
},
|
||||||
|
|
||||||
regions: {
|
regions: {
|
||||||
@ -73,6 +75,7 @@ module.exports = Mn.View.extend({
|
|||||||
let data = {
|
let data = {
|
||||||
name: form_data.name,
|
name: form_data.name,
|
||||||
satisfy_any: !!form_data.satisfy_any,
|
satisfy_any: !!form_data.satisfy_any,
|
||||||
|
pass_auth: !!form_data.pass_auth,
|
||||||
items: items_data,
|
items: items_data,
|
||||||
clients: clients_data
|
clients: clients_data
|
||||||
};
|
};
|
||||||
@ -104,6 +107,24 @@ module.exports = Mn.View.extend({
|
|||||||
alert(err.message);
|
alert(err.message);
|
||||||
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
|
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
'click @ui.access_add': function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
let clients = this.model.get('clients');
|
||||||
|
clients.push({});
|
||||||
|
this.showChildView('clients_region', new ClientsView({
|
||||||
|
collection: new Backbone.Collection(clients)
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
'click @ui.auth_add': function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
let items = this.model.get('items');
|
||||||
|
items.push({});
|
||||||
|
this.showChildView('items_region', new ItemsView({
|
||||||
|
collection: new Backbone.Collection(items)
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -111,20 +132,9 @@ module.exports = Mn.View.extend({
|
|||||||
let items = this.model.get('items');
|
let items = this.model.get('items');
|
||||||
let clients = this.model.get('clients');
|
let clients = this.model.get('clients');
|
||||||
|
|
||||||
// Add empty items to the end of the list. This is cheating but hey I don't have the time to do it right
|
// Ensure at least one field is shown initally
|
||||||
let items_to_add = 5 - items.length;
|
if (!items.length) items.push({});
|
||||||
if (items_to_add) {
|
if (!clients.length) clients.push({});
|
||||||
for (let i = 0; i < items_to_add; i++) {
|
|
||||||
items.push({});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let clients_to_add = 4 - clients.length;
|
|
||||||
if (clients_to_add) {
|
|
||||||
for (let i = 0; i < clients_to_add; i++) {
|
|
||||||
clients.push({});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.showChildView('items_region', new ItemsView({
|
this.showChildView('items_region', new ItemsView({
|
||||||
collection: new Backbone.Collection(items)
|
collection: new Backbone.Collection(items)
|
||||||
|
@ -8,6 +8,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-sm-9 col-md-9">
|
<div class="col-sm-9 col-md-9">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="text" name="address[]" class="form-control" value="<%- typeof address !== 'undefined' ? address : '' %>" value="">
|
<input type="text" name="address[]" placeholder="IP / Subnet" class="form-control" value="<%- typeof address !== 'undefined' ? address : '' %>" value="">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,6 +16,8 @@ module.exports = Mn.View.extend({
|
|||||||
events: {
|
events: {
|
||||||
'click @ui.save': function (e) {
|
'click @ui.save': function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
this.ui.save.addClass('btn-loading');
|
||||||
|
this.ui.buttons.prop('disabled', true).addClass('btn-disabled');
|
||||||
|
|
||||||
App.Api.Nginx.Certificates.delete(this.model.get('id'))
|
App.Api.Nginx.Certificates.delete(this.model.get('id'))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -25,6 +27,7 @@ module.exports = Mn.View.extend({
|
|||||||
.catch(err => {
|
.catch(err => {
|
||||||
alert(err.message);
|
alert(err.message);
|
||||||
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
|
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
|
||||||
|
this.ui.save.removeClass('btn-loading');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title"><%- i18n('certificates', 'form-title', {provider: provider}) %></h5>
|
<h5 class="modal-title"><%- i18n('certificates', 'form-title', {provider: provider}) %></h5>
|
||||||
<button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button>
|
<button type="button" class="close cancel non-loader-content" aria-label="Close" data-dismiss="modal"> </button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<form>
|
<div class="alert alert-danger mb-0 rounded-0" id="le-error-info" role="alert"></div>
|
||||||
|
<div class="text-center loader-content">
|
||||||
|
<div class="loader mx-auto my-6"></div>
|
||||||
|
<p><%- i18n('ssl', 'processing-info') %></p>
|
||||||
|
</div>
|
||||||
|
<form class="non-loader-content">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<% if (provider === 'letsencrypt') { %>
|
<% if (provider === 'letsencrypt') { %>
|
||||||
<div class="col-sm-12 col-md-12">
|
<div class="col-sm-12 col-md-12">
|
||||||
@ -21,21 +26,96 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- CloudFlare -->
|
<!-- DNS challenge -->
|
||||||
<div class="col-sm-12 col-md-12">
|
<div class="col-sm-12 col-md-12">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="custom-switch">
|
<label class="custom-switch">
|
||||||
<input type="checkbox" class="custom-switch-input" name="meta[cloudflare_use]" value="1">
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
class="custom-switch-input"
|
||||||
|
name="meta[dns_challenge]"
|
||||||
|
value="1"
|
||||||
|
<%- getUseDnsChallenge() ? 'checked' : '' %>
|
||||||
|
>
|
||||||
<span class="custom-switch-indicator"></span>
|
<span class="custom-switch-indicator"></span>
|
||||||
<span class="custom-switch-description"><%= i18n('ssl', 'use-cloudflare') %></span>
|
<span class="custom-switch-description"><%= i18n('ssl', 'dns-challenge') %></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12 col-md-12 cloudflare">
|
<div class="col-sm-12 col-md-12">
|
||||||
<div class="form-group">
|
<fieldset class="form-fieldset dns-challenge">
|
||||||
<label class="form-label">CloudFlare DNS API Token <span class="form-required">*</span></label>
|
<div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('ssl', 'certbot-warning') %></div>
|
||||||
<input type="text" name="meta[cloudflare_token]" class="form-control" id="cloudflare_token">
|
|
||||||
</div>
|
<!-- Certbot DNS plugin selection -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label"><%- i18n('ssl', 'dns-provider') %> <span class="form-required">*</span></label>
|
||||||
|
<select
|
||||||
|
name="meta[dns_provider]"
|
||||||
|
id="dns_provider"
|
||||||
|
class="form-control custom-select"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
value=""
|
||||||
|
disabled
|
||||||
|
hidden
|
||||||
|
<%- getDnsProvider() === null ? 'selected' : '' %>
|
||||||
|
>Please Choose...</option>
|
||||||
|
<% _.each(dns_plugins, function(plugin_info, plugin_name){ %>
|
||||||
|
<option
|
||||||
|
value="<%- plugin_name %>"
|
||||||
|
<%- getDnsProvider() === plugin_name ? 'selected' : '' %>
|
||||||
|
><%- plugin_info.display_name %></option>
|
||||||
|
<% }); %>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Certbot credentials file content -->
|
||||||
|
<div class="row credentials-file-content">
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label"><%- i18n('ssl', 'credentials-file-content') %> <span class="form-required">*</span></label>
|
||||||
|
<textarea
|
||||||
|
name="meta[dns_provider_credentials]"
|
||||||
|
class="form-control text-monospace"
|
||||||
|
id="dns_provider_credentials"
|
||||||
|
><%- getDnsProviderCredentials() %></textarea>
|
||||||
|
<div class="text-secondary small">
|
||||||
|
<i class="fe fe-info"></i>
|
||||||
|
<%= i18n('ssl', 'credentials-file-content-info') %>
|
||||||
|
</div>
|
||||||
|
<div class="text-red small">
|
||||||
|
<i class="fe fe-alert-triangle"></i>
|
||||||
|
<%= i18n('ssl', 'stored-as-plaintext-info') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- DNS propagation delay -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group mb-0">
|
||||||
|
<label class="form-label"><%- i18n('ssl', 'propagation-seconds') %></label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
name="meta[propagation_seconds]"
|
||||||
|
class="form-control"
|
||||||
|
id="propagation_seconds"
|
||||||
|
value="<%- getPropagationSeconds() %>"
|
||||||
|
>
|
||||||
|
<div class="text-secondary small">
|
||||||
|
<i class="fe fe-info"></i>
|
||||||
|
<%= i18n('ssl', 'propagation-seconds-info') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-12 col-md-12">
|
<div class="col-sm-12 col-md-12">
|
||||||
@ -49,6 +129,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<% } else if (provider === 'other') { %>
|
<% } else if (provider === 'other') { %>
|
||||||
<!-- Other -->
|
<!-- Other -->
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="text-blue mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('ssl', 'passphrase-protection-support-info') %></div>
|
||||||
|
</div>
|
||||||
<div class="col-sm-12 col-md-12">
|
<div class="col-sm-12 col-md-12">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label"><%- i18n('str', 'name') %> <span class="form-required">*</span></label>
|
<label class="form-label"><%- i18n('str', 'name') %> <span class="form-required">*</span></label>
|
||||||
@ -87,7 +170,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer non-loader-content">
|
||||||
<button type="button" class="btn btn-secondary cancel" data-dismiss="modal"><%- i18n('str', 'cancel') %></button>
|
<button type="button" class="btn btn-secondary cancel" data-dismiss="modal"><%- i18n('str', 'cancel') %></button>
|
||||||
<button type="button" class="btn btn-teal save"><%- i18n('str', 'save') %></button>
|
<button type="button" class="btn btn-teal save"><%- i18n('str', 'save') %></button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,6 +3,8 @@ const Mn = require('backbone.marionette');
|
|||||||
const App = require('../../main');
|
const App = require('../../main');
|
||||||
const CertificateModel = require('../../../models/certificate');
|
const CertificateModel = require('../../../models/certificate');
|
||||||
const template = require('./form.ejs');
|
const template = require('./form.ejs');
|
||||||
|
const i18n = require('../../i18n');
|
||||||
|
const dns_providers = require('../../../../../global/certbot-dns-plugins');
|
||||||
|
|
||||||
require('jquery-serializejson');
|
require('jquery-serializejson');
|
||||||
require('selectize');
|
require('selectize');
|
||||||
@ -14,6 +16,9 @@ module.exports = Mn.View.extend({
|
|||||||
|
|
||||||
ui: {
|
ui: {
|
||||||
form: 'form',
|
form: 'form',
|
||||||
|
loader_content: '.loader-content',
|
||||||
|
non_loader_content: '.non-loader-content',
|
||||||
|
le_error_info: '#le-error-info',
|
||||||
domain_names: 'input[name="domain_names"]',
|
domain_names: 'input[name="domain_names"]',
|
||||||
buttons: '.modal-footer button',
|
buttons: '.modal-footer button',
|
||||||
cancel: 'button.cancel',
|
cancel: 'button.cancel',
|
||||||
@ -21,27 +26,49 @@ module.exports = Mn.View.extend({
|
|||||||
other_certificate: '#other_certificate',
|
other_certificate: '#other_certificate',
|
||||||
other_certificate_label: '#other_certificate_label',
|
other_certificate_label: '#other_certificate_label',
|
||||||
other_certificate_key: '#other_certificate_key',
|
other_certificate_key: '#other_certificate_key',
|
||||||
cloudflare_switch: 'input[name="meta[cloudflare_use]"]',
|
dns_challenge_switch: 'input[name="meta[dns_challenge]"]',
|
||||||
cloudflare_token: 'input[name="meta[cloudflare_token]"',
|
dns_challenge_content: '.dns-challenge',
|
||||||
cloudflare: '.cloudflare',
|
dns_provider: 'select[name="meta[dns_provider]"]',
|
||||||
|
credentials_file_content: '.credentials-file-content',
|
||||||
|
dns_provider_credentials: 'textarea[name="meta[dns_provider_credentials]"]',
|
||||||
|
propagation_seconds: 'input[name="meta[propagation_seconds]"]',
|
||||||
other_certificate_key_label: '#other_certificate_key_label',
|
other_certificate_key_label: '#other_certificate_key_label',
|
||||||
other_intermediate_certificate: '#other_intermediate_certificate',
|
other_intermediate_certificate: '#other_intermediate_certificate',
|
||||||
other_intermediate_certificate_label: '#other_intermediate_certificate_label'
|
other_intermediate_certificate_label: '#other_intermediate_certificate_label'
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
'change @ui.cloudflare_switch': function() {
|
'change @ui.dns_challenge_switch': function () {
|
||||||
let checked = this.ui.cloudflare_switch.prop('checked');
|
const checked = this.ui.dns_challenge_switch.prop('checked');
|
||||||
if (checked) {
|
if (checked) {
|
||||||
this.ui.cloudflare_token.prop('required', 'required');
|
this.ui.dns_provider.prop('required', 'required');
|
||||||
this.ui.cloudflare.show();
|
const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value;
|
||||||
} else {
|
if(selected_provider != '' && dns_providers[selected_provider].credentials !== false){
|
||||||
this.ui.cloudflare_token.prop('required', false);
|
this.ui.dns_provider_credentials.prop('required', 'required');
|
||||||
this.ui.cloudflare.hide();
|
}
|
||||||
|
this.ui.dns_challenge_content.show();
|
||||||
|
} else {
|
||||||
|
this.ui.dns_provider.prop('required', false);
|
||||||
|
this.ui.dns_provider_credentials.prop('required', false);
|
||||||
|
this.ui.dns_challenge_content.hide();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'change @ui.dns_provider': function () {
|
||||||
|
const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value;
|
||||||
|
if (selected_provider != '' && dns_providers[selected_provider].credentials !== false) {
|
||||||
|
this.ui.dns_provider_credentials.prop('required', 'required');
|
||||||
|
this.ui.dns_provider_credentials[0].value = dns_providers[selected_provider].credentials;
|
||||||
|
this.ui.credentials_file_content.show();
|
||||||
|
} else {
|
||||||
|
this.ui.dns_provider_credentials.prop('required', false);
|
||||||
|
this.ui.credentials_file_content.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
'click @ui.save': function (e) {
|
'click @ui.save': function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
this.ui.le_error_info.hide();
|
||||||
|
|
||||||
if (!this.ui.form[0].checkValidity()) {
|
if (!this.ui.form[0].checkValidity()) {
|
||||||
$('<input type="submit">').hide().appendTo(this.ui.form).click().remove();
|
$('<input type="submit">').hide().appendTo(this.ui.form).click().remove();
|
||||||
@ -49,42 +76,44 @@ module.exports = Mn.View.extend({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let view = this;
|
|
||||||
let data = this.ui.form.serializeJSON();
|
let data = this.ui.form.serializeJSON();
|
||||||
data.provider = this.model.get('provider');
|
data.provider = this.model.get('provider');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let domain_err = false;
|
|
||||||
if (!data.meta.cloudflare_use) {
|
|
||||||
data.domain_names.split(',').map(function (name) {
|
|
||||||
if (name.match(/\*/im)) {
|
|
||||||
domain_err = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (domain_err) {
|
|
||||||
alert('Cannot request Let\'s Encrypt Certificate for wildcard domains when not using CloudFlare DNS');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manipulate
|
|
||||||
if (typeof data.meta !== 'undefined' && typeof data.meta.letsencrypt_agree !== 'undefined') {
|
|
||||||
data.meta.letsencrypt_agree = !!data.meta.letsencrypt_agree;
|
|
||||||
}
|
|
||||||
if (typeof data.meta !== 'undefined' && typeof data.meta.cloudflare_use !== 'undefined') {
|
|
||||||
data.meta.cloudflare_use = !!data.meta.cloudflare_use;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof data.domain_names === 'string' && data.domain_names) {
|
|
||||||
data.domain_names = data.domain_names.split(',');
|
|
||||||
}
|
|
||||||
|
|
||||||
let ssl_files = [];
|
let ssl_files = [];
|
||||||
|
|
||||||
// check files are attached
|
if (data.provider === 'letsencrypt') {
|
||||||
if (this.model.get('provider') === 'other' && !this.model.hasSslFiles()) {
|
if (typeof data.meta === 'undefined') data.meta = {};
|
||||||
|
|
||||||
|
let domain_err = false;
|
||||||
|
if (!data.meta.dns_challenge) {
|
||||||
|
data.domain_names.split(',').map(function (name) {
|
||||||
|
if (name.match(/\*/im)) {
|
||||||
|
domain_err = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domain_err) {
|
||||||
|
alert(i18n('ssl', 'no-wildcard-without-dns'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Manipulate
|
||||||
|
data.meta.letsencrypt_agree = data.meta.letsencrypt_agree == 1;
|
||||||
|
data.meta.dns_challenge = data.meta.dns_challenge == 1;
|
||||||
|
|
||||||
|
if(!data.meta.dns_challenge){
|
||||||
|
data.meta.dns_provider = undefined;
|
||||||
|
data.meta.dns_provider_credentials = undefined;
|
||||||
|
data.meta.propagation_seconds = undefined;
|
||||||
|
} else {
|
||||||
|
if(data.meta.propagation_seconds === '') data.meta.propagation_seconds = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof data.domain_names === 'string' && data.domain_names) {
|
||||||
|
data.domain_names = data.domain_names.split(',');
|
||||||
|
}
|
||||||
|
} else if (data.provider === 'other' && !this.model.hasSslFiles()) {
|
||||||
|
// check files are attached
|
||||||
if (!this.ui.other_certificate[0].files.length || !this.ui.other_certificate[0].files[0].size) {
|
if (!this.ui.other_certificate[0].files.length || !this.ui.other_certificate[0].files[0].size) {
|
||||||
alert('Certificate file is not attached');
|
alert('Certificate file is not attached');
|
||||||
return;
|
return;
|
||||||
@ -116,19 +145,19 @@ module.exports = Mn.View.extend({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ui.buttons.prop('disabled', true).addClass('btn-disabled');
|
this.ui.loader_content.show();
|
||||||
this.ui.save.addClass('btn-loading');
|
this.ui.non_loader_content.hide();
|
||||||
|
|
||||||
// compile file data
|
// compile file data
|
||||||
let form_data = new FormData();
|
let form_data = new FormData();
|
||||||
if (view.model.get('provider') && ssl_files.length) {
|
if (data.provider === 'other' && ssl_files.length) {
|
||||||
ssl_files.map(function (file) {
|
ssl_files.map(function (file) {
|
||||||
form_data.append(file.name, file.file);
|
form_data.append(file.name, file.file);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
new Promise(resolve => {
|
new Promise(resolve => {
|
||||||
if (view.model.get('provider') === 'other') {
|
if (data.provider === 'other') {
|
||||||
resolve(App.Api.Nginx.Certificates.validate(form_data));
|
resolve(App.Api.Nginx.Certificates.validate(form_data));
|
||||||
} else {
|
} else {
|
||||||
resolve();
|
resolve();
|
||||||
@ -138,13 +167,13 @@ module.exports = Mn.View.extend({
|
|||||||
return App.Api.Nginx.Certificates.create(data);
|
return App.Api.Nginx.Certificates.create(data);
|
||||||
})
|
})
|
||||||
.then(result => {
|
.then(result => {
|
||||||
view.model.set(result);
|
this.model.set(result);
|
||||||
|
|
||||||
// Now upload the certs if we need to
|
// Now upload the certs if we need to
|
||||||
if (view.model.get('provider') === 'other') {
|
if (data.provider === 'other') {
|
||||||
return App.Api.Nginx.Certificates.upload(view.model.get('id'), form_data)
|
return App.Api.Nginx.Certificates.upload(this.model.get('id'), form_data)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
view.model.set('meta', _.assign({}, view.model.get('meta'), result));
|
this.model.set('meta', _.assign({}, this.model.get('meta'), result));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -154,9 +183,17 @@ module.exports = Mn.View.extend({
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
alert(err.message);
|
let more_info = '';
|
||||||
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
|
if (err.code === 500 && err.debug) {
|
||||||
this.ui.save.removeClass('btn-loading');
|
try{
|
||||||
|
more_info = JSON.parse(err.debug).debug.stack.join("\n");
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
this.ui.le_error_info[0].innerHTML = `${err.message}${more_info !== '' ? `<pre class="mt-3">${more_info}</pre>`:''}`;
|
||||||
|
this.ui.le_error_info.show();
|
||||||
|
this.ui.le_error_info[0].scrollIntoView();
|
||||||
|
this.ui.loader_content.hide();
|
||||||
|
this.ui.non_loader_content.show();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
'change @ui.other_certificate_key': function(e){
|
'change @ui.other_certificate_key': function(e){
|
||||||
@ -176,14 +213,22 @@ module.exports = Mn.View.extend({
|
|||||||
getLetsencryptEmail: function () {
|
getLetsencryptEmail: function () {
|
||||||
return typeof this.meta.letsencrypt_email !== 'undefined' ? this.meta.letsencrypt_email : App.Cache.User.get('email');
|
return typeof this.meta.letsencrypt_email !== 'undefined' ? this.meta.letsencrypt_email : App.Cache.User.get('email');
|
||||||
},
|
},
|
||||||
|
|
||||||
getLetsencryptAgree: function () {
|
getLetsencryptAgree: function () {
|
||||||
return typeof this.meta.letsencrypt_agree !== 'undefined' ? this.meta.letsencrypt_agree : false;
|
return typeof this.meta.letsencrypt_agree !== 'undefined' ? this.meta.letsencrypt_agree : false;
|
||||||
},
|
},
|
||||||
|
getUseDnsChallenge: function () {
|
||||||
getCloudflareUse: function () {
|
return typeof this.meta.dns_challenge !== 'undefined' ? this.meta.dns_challenge : false;
|
||||||
return typeof this.meta.cloudflare_use !== 'undefined' ? this.meta.cloudflare_use : false;
|
},
|
||||||
}
|
getDnsProvider: function () {
|
||||||
|
return typeof this.meta.dns_provider !== 'undefined' && this.meta.dns_provider != '' ? this.meta.dns_provider : null;
|
||||||
|
},
|
||||||
|
getDnsProviderCredentials: function () {
|
||||||
|
return typeof this.meta.dns_provider_credentials !== 'undefined' ? this.meta.dns_provider_credentials : '';
|
||||||
|
},
|
||||||
|
getPropagationSeconds: function () {
|
||||||
|
return typeof this.meta.propagation_seconds !== 'undefined' ? this.meta.propagation_seconds : '';
|
||||||
|
},
|
||||||
|
dns_plugins: dns_providers,
|
||||||
},
|
},
|
||||||
|
|
||||||
onRender: function () {
|
onRender: function () {
|
||||||
@ -199,7 +244,10 @@ module.exports = Mn.View.extend({
|
|||||||
},
|
},
|
||||||
createFilter: /^(?:[^.]+\.?)+[^.]$/
|
createFilter: /^(?:[^.]+\.?)+[^.]$/
|
||||||
});
|
});
|
||||||
this.ui.cloudflare.hide();
|
this.ui.dns_challenge_content.hide();
|
||||||
|
this.ui.credentials_file_content.hide();
|
||||||
|
this.ui.loader_content.hide();
|
||||||
|
this.ui.le_error_info.hide();
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function (options) {
|
initialize: function (options) {
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<%- i18n('ssl', provider) %><% if (meta.cloudflare_use) { %> - CloudFlare DNS<% } %>
|
<%- i18n('ssl', provider) %><% if (meta.dns_provider) { %> - <%- dns_providers[meta.dns_provider].display_name %><% } %>
|
||||||
</td>
|
</td>
|
||||||
<td class="<%- isExpired() ? 'text-danger' : '' %>">
|
<td class="<%- isExpired() ? 'text-danger' : '' %>">
|
||||||
<%- formatDbDate(expires_on, 'Do MMMM YYYY, h:mm a') %>
|
<%- formatDbDate(expires_on, 'Do MMMM YYYY, h:mm a') %>
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
const Mn = require('backbone.marionette');
|
const Mn = require('backbone.marionette');
|
||||||
const moment = require('moment');
|
const moment = require('moment');
|
||||||
const App = require('../../../main');
|
const App = require('../../../main');
|
||||||
const template = require('./item.ejs');
|
const template = require('./item.ejs');
|
||||||
|
const dns_providers = require('../../../../../../global/certbot-dns-plugins')
|
||||||
|
|
||||||
module.exports = Mn.View.extend({
|
module.exports = Mn.View.extend({
|
||||||
template: template,
|
template: template,
|
||||||
@ -35,7 +36,8 @@ module.exports = Mn.View.extend({
|
|||||||
canManage: App.Cache.User.canManage('certificates'),
|
canManage: App.Cache.User.canManage('certificates'),
|
||||||
isExpired: function () {
|
isExpired: function () {
|
||||||
return moment(this.expires_on).isBefore(moment());
|
return moment(this.expires_on).isBefore(moment());
|
||||||
}
|
},
|
||||||
|
dns_providers: dns_providers
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function () {
|
initialize: function () {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
<button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button>
|
<button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body has-tabs">
|
<div class="modal-body has-tabs">
|
||||||
|
<div class="alert alert-danger mb-0 rounded-0" id="le-error-info" role="alert"></div>
|
||||||
<form>
|
<form>
|
||||||
<ul class="nav nav-tabs" role="tablist">
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
<li role="presentation" class="nav-item"><a href="#details" aria-controls="tab1" role="tab" data-toggle="tab" class="nav-link active"><i class="fe fe-zap"></i> <%- i18n('all-hosts', 'details') %></a></li>
|
<li role="presentation" class="nav-item"><a href="#details" aria-controls="tab1" role="tab" data-toggle="tab" class="nav-link active"><i class="fe fe-zap"></i> <%- i18n('all-hosts', 'details') %></a></li>
|
||||||
@ -73,21 +74,96 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- CloudFlare -->
|
<!-- DNS challenge -->
|
||||||
<div class="col-sm-12 col-md-12 letsencrypt">
|
<div class="col-sm-12 col-md-12 letsencrypt">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="custom-switch">
|
<label class="custom-switch">
|
||||||
<input type="checkbox" class="custom-switch-input" name="meta[cloudflare_use]" value="1">
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
class="custom-switch-input"
|
||||||
|
name="meta[dns_challenge]"
|
||||||
|
value="1"
|
||||||
|
<%- getUseDnsChallenge() ? 'checked' : '' %>
|
||||||
|
>
|
||||||
<span class="custom-switch-indicator"></span>
|
<span class="custom-switch-indicator"></span>
|
||||||
<span class="custom-switch-description"><%= i18n('ssl', 'use-cloudflare') %></span>
|
<span class="custom-switch-description"><%= i18n('ssl', 'dns-challenge') %></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12 col-md-12 cloudflare letsencrypt">
|
<div class="col-sm-12 col-md-12 letsencrypt">
|
||||||
<div class="form-group">
|
<fieldset class="form-fieldset dns-challenge">
|
||||||
<label class="form-label">CloudFlare DNS API Token <span class="form-required">*</span></label>
|
<div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('ssl', 'certbot-warning') %></div>
|
||||||
<input type="text" name="meta[cloudflare_token]" class="form-control" id="cloudflare_token">
|
|
||||||
</div>
|
<!-- Certbot DNS plugin selection -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label"><%- i18n('ssl', 'dns-provider') %> <span class="form-required">*</span></label>
|
||||||
|
<select
|
||||||
|
name="meta[dns_provider]"
|
||||||
|
id="dns_provider"
|
||||||
|
class="form-control custom-select"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
value=""
|
||||||
|
disabled
|
||||||
|
hidden
|
||||||
|
<%- getDnsProvider() === null ? 'selected' : '' %>
|
||||||
|
>Please Choose...</option>
|
||||||
|
<% _.each(dns_plugins, function(plugin_info, plugin_name){ %>
|
||||||
|
<option
|
||||||
|
value="<%- plugin_name %>"
|
||||||
|
<%- getDnsProvider() === plugin_name ? 'selected' : '' %>
|
||||||
|
><%- plugin_info.display_name %></option>
|
||||||
|
<% }); %>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Certbot credentials file content -->
|
||||||
|
<div class="row credentials-file-content">
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label"><%- i18n('ssl', 'credentials-file-content') %> <span class="form-required">*</span></label>
|
||||||
|
<textarea
|
||||||
|
name="meta[dns_provider_credentials]"
|
||||||
|
class="form-control text-monospace"
|
||||||
|
id="dns_provider_credentials"
|
||||||
|
><%- getDnsProviderCredentials() %></textarea>
|
||||||
|
<div class="text-secondary small">
|
||||||
|
<i class="fe fe-info"></i>
|
||||||
|
<%= i18n('ssl', 'credentials-file-content-info') %>
|
||||||
|
</div>
|
||||||
|
<div class="text-red small">
|
||||||
|
<i class="fe fe-alert-triangle"></i>
|
||||||
|
<%= i18n('ssl', 'stored-as-plaintext-info') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- DNS propagation delay -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group mb-0">
|
||||||
|
<label class="form-label"><%- i18n('ssl', 'propagation-seconds') %></label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
name="meta[propagation_seconds]"
|
||||||
|
class="form-control"
|
||||||
|
id="propagation_seconds"
|
||||||
|
value="<%- getPropagationSeconds() %>"
|
||||||
|
>
|
||||||
|
<div class="text-secondary small">
|
||||||
|
<i class="fe fe-info"></i>
|
||||||
|
<%= i18n('ssl', 'propagation-seconds-info') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Lets encrypt -->
|
<!-- Lets encrypt -->
|
||||||
|
@ -4,6 +4,8 @@ const DeadHostModel = require('../../../models/dead-host');
|
|||||||
const template = require('./form.ejs');
|
const template = require('./form.ejs');
|
||||||
const certListItemTemplate = require('../certificates-list-item.ejs');
|
const certListItemTemplate = require('../certificates-list-item.ejs');
|
||||||
const Helpers = require('../../../lib/helpers');
|
const Helpers = require('../../../lib/helpers');
|
||||||
|
const i18n = require('../../i18n');
|
||||||
|
const dns_providers = require('../../../../../global/certbot-dns-plugins');
|
||||||
|
|
||||||
require('jquery-serializejson');
|
require('jquery-serializejson');
|
||||||
require('selectize');
|
require('selectize');
|
||||||
@ -13,20 +15,24 @@ module.exports = Mn.View.extend({
|
|||||||
className: 'modal-dialog',
|
className: 'modal-dialog',
|
||||||
|
|
||||||
ui: {
|
ui: {
|
||||||
form: 'form',
|
form: 'form',
|
||||||
domain_names: 'input[name="domain_names"]',
|
domain_names: 'input[name="domain_names"]',
|
||||||
buttons: '.modal-footer button',
|
buttons: '.modal-footer button',
|
||||||
cancel: 'button.cancel',
|
cancel: 'button.cancel',
|
||||||
save: 'button.save',
|
save: 'button.save',
|
||||||
certificate_select: 'select[name="certificate_id"]',
|
le_error_info: '#le-error-info',
|
||||||
ssl_forced: 'input[name="ssl_forced"]',
|
certificate_select: 'select[name="certificate_id"]',
|
||||||
hsts_enabled: 'input[name="hsts_enabled"]',
|
ssl_forced: 'input[name="ssl_forced"]',
|
||||||
hsts_subdomains: 'input[name="hsts_subdomains"]',
|
hsts_enabled: 'input[name="hsts_enabled"]',
|
||||||
http2_support: 'input[name="http2_support"]',
|
hsts_subdomains: 'input[name="hsts_subdomains"]',
|
||||||
cloudflare_switch: 'input[name="meta[cloudflare_use]"]',
|
http2_support: 'input[name="http2_support"]',
|
||||||
cloudflare_token: 'input[name="meta[cloudflare_token]"',
|
dns_challenge_switch: 'input[name="meta[dns_challenge]"]',
|
||||||
cloudflare: '.cloudflare',
|
dns_challenge_content: '.dns-challenge',
|
||||||
letsencrypt: '.letsencrypt'
|
dns_provider: 'select[name="meta[dns_provider]"]',
|
||||||
|
credentials_file_content: '.credentials-file-content',
|
||||||
|
dns_provider_credentials: 'textarea[name="meta[dns_provider_credentials]"]',
|
||||||
|
propagation_seconds: 'input[name="meta[propagation_seconds]"]',
|
||||||
|
letsencrypt: '.letsencrypt'
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
@ -34,7 +40,7 @@ module.exports = Mn.View.extend({
|
|||||||
let id = this.ui.certificate_select.val();
|
let id = this.ui.certificate_select.val();
|
||||||
if (id === 'new') {
|
if (id === 'new') {
|
||||||
this.ui.letsencrypt.show().find('input').prop('disabled', false);
|
this.ui.letsencrypt.show().find('input').prop('disabled', false);
|
||||||
this.ui.cloudflare.hide();
|
this.ui.dns_challenge_content.hide();
|
||||||
} else {
|
} else {
|
||||||
this.ui.letsencrypt.hide().find('input').prop('disabled', true);
|
this.ui.letsencrypt.hide().find('input').prop('disabled', true);
|
||||||
}
|
}
|
||||||
@ -81,19 +87,37 @@ module.exports = Mn.View.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'change @ui.cloudflare_switch': function() {
|
'change @ui.dns_challenge_switch': function () {
|
||||||
let checked = this.ui.cloudflare_switch.prop('checked');
|
const checked = this.ui.dns_challenge_switch.prop('checked');
|
||||||
if (checked) {
|
if (checked) {
|
||||||
this.ui.cloudflare_token.prop('required', 'required');
|
this.ui.dns_provider.prop('required', 'required');
|
||||||
this.ui.cloudflare.show();
|
const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value;
|
||||||
} else {
|
if(selected_provider != '' && dns_providers[selected_provider].credentials !== false){
|
||||||
this.ui.cloudflare_token.prop('required', false);
|
this.ui.dns_provider_credentials.prop('required', 'required');
|
||||||
this.ui.cloudflare.hide();
|
}
|
||||||
|
this.ui.dns_challenge_content.show();
|
||||||
|
} else {
|
||||||
|
this.ui.dns_provider.prop('required', false);
|
||||||
|
this.ui.dns_provider_credentials.prop('required', false);
|
||||||
|
this.ui.dns_challenge_content.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'change @ui.dns_provider': function () {
|
||||||
|
const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value;
|
||||||
|
if (selected_provider != '' && dns_providers[selected_provider].credentials !== false) {
|
||||||
|
this.ui.dns_provider_credentials.prop('required', 'required');
|
||||||
|
this.ui.dns_provider_credentials[0].value = dns_providers[selected_provider].credentials;
|
||||||
|
this.ui.credentials_file_content.show();
|
||||||
|
} else {
|
||||||
|
this.ui.dns_provider_credentials.prop('required', false);
|
||||||
|
this.ui.credentials_file_content.hide();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'click @ui.save': function (e) {
|
'click @ui.save': function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
this.ui.le_error_info.hide();
|
||||||
|
|
||||||
if (!this.ui.form[0].checkValidity()) {
|
if (!this.ui.form[0].checkValidity()) {
|
||||||
$('<input type="submit">').hide().appendTo(this.ui.form).click().remove();
|
$('<input type="submit">').hide().appendTo(this.ui.form).click().remove();
|
||||||
@ -104,10 +128,22 @@ module.exports = Mn.View.extend({
|
|||||||
let data = this.ui.form.serializeJSON();
|
let data = this.ui.form.serializeJSON();
|
||||||
|
|
||||||
// Manipulate
|
// Manipulate
|
||||||
data.hsts_enabled = !!data.hsts_enabled;
|
data.hsts_enabled = !!data.hsts_enabled;
|
||||||
data.hsts_subdomains = !!data.hsts_subdomains;
|
data.hsts_subdomains = !!data.hsts_subdomains;
|
||||||
data.http2_support = !!data.http2_support;
|
data.http2_support = !!data.http2_support;
|
||||||
data.ssl_forced = !!data.ssl_forced;
|
data.ssl_forced = !!data.ssl_forced;
|
||||||
|
|
||||||
|
if (typeof data.meta === 'undefined') data.meta = {};
|
||||||
|
data.meta.letsencrypt_agree = data.meta.letsencrypt_agree == 1;
|
||||||
|
data.meta.dns_challenge = data.meta.dns_challenge == 1;
|
||||||
|
|
||||||
|
if(!data.meta.dns_challenge){
|
||||||
|
data.meta.dns_provider = undefined;
|
||||||
|
data.meta.dns_provider_credentials = undefined;
|
||||||
|
data.meta.propagation_seconds = undefined;
|
||||||
|
} else {
|
||||||
|
if(data.meta.propagation_seconds === '') data.meta.propagation_seconds = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof data.domain_names === 'string' && data.domain_names) {
|
if (typeof data.domain_names === 'string' && data.domain_names) {
|
||||||
data.domain_names = data.domain_names.split(',');
|
data.domain_names = data.domain_names.split(',');
|
||||||
@ -116,7 +152,7 @@ module.exports = Mn.View.extend({
|
|||||||
// Check for any domain names containing wildcards, which are not allowed with letsencrypt
|
// Check for any domain names containing wildcards, which are not allowed with letsencrypt
|
||||||
if (data.certificate_id === 'new') {
|
if (data.certificate_id === 'new') {
|
||||||
let domain_err = false;
|
let domain_err = false;
|
||||||
if (!data.meta.cloudflare_use) {
|
if (!data.meta.dns_challenge) {
|
||||||
data.domain_names.map(function (name) {
|
data.domain_names.map(function (name) {
|
||||||
if (name.match(/\*/im)) {
|
if (name.match(/\*/im)) {
|
||||||
domain_err = true;
|
domain_err = true;
|
||||||
@ -125,12 +161,9 @@ module.exports = Mn.View.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (domain_err) {
|
if (domain_err) {
|
||||||
alert('Cannot request Let\'s Encrypt Certificate for wildcard domains without CloudFlare DNS.');
|
alert(i18n('ssl', 'no-wildcard-without-dns'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.meta.cloudflare_use = data.meta.cloudflare_use === '1';
|
|
||||||
data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';
|
|
||||||
} else {
|
} else {
|
||||||
data.certificate_id = parseInt(data.certificate_id, 10);
|
data.certificate_id = parseInt(data.certificate_id, 10);
|
||||||
}
|
}
|
||||||
@ -159,7 +192,15 @@ module.exports = Mn.View.extend({
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
alert(err.message);
|
let more_info = '';
|
||||||
|
if(err.code === 500 && err.debug){
|
||||||
|
try{
|
||||||
|
more_info = JSON.parse(err.debug).debug.stack.join("\n");
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
this.ui.le_error_info[0].innerHTML = `${err.message}${more_info !== '' ? `<pre class="mt-3">${more_info}</pre>`:''}`;
|
||||||
|
this.ui.le_error_info.show();
|
||||||
|
this.ui.le_error_info[0].scrollIntoView();
|
||||||
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
|
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
|
||||||
this.ui.save.removeClass('btn-loading');
|
this.ui.save.removeClass('btn-loading');
|
||||||
});
|
});
|
||||||
@ -169,7 +210,20 @@ module.exports = Mn.View.extend({
|
|||||||
templateContext: {
|
templateContext: {
|
||||||
getLetsencryptEmail: function () {
|
getLetsencryptEmail: function () {
|
||||||
return App.Cache.User.get('email');
|
return App.Cache.User.get('email');
|
||||||
}
|
},
|
||||||
|
getUseDnsChallenge: function () {
|
||||||
|
return typeof this.meta.dns_challenge !== 'undefined' ? this.meta.dns_challenge : false;
|
||||||
|
},
|
||||||
|
getDnsProvider: function () {
|
||||||
|
return typeof this.meta.dns_provider !== 'undefined' && this.meta.dns_provider != '' ? this.meta.dns_provider : null;
|
||||||
|
},
|
||||||
|
getDnsProviderCredentials: function () {
|
||||||
|
return typeof this.meta.dns_provider_credentials !== 'undefined' ? this.meta.dns_provider_credentials : '';
|
||||||
|
},
|
||||||
|
getPropagationSeconds: function () {
|
||||||
|
return typeof this.meta.propagation_seconds !== 'undefined' ? this.meta.propagation_seconds : '';
|
||||||
|
},
|
||||||
|
dns_plugins: dns_providers,
|
||||||
},
|
},
|
||||||
|
|
||||||
onRender: function () {
|
onRender: function () {
|
||||||
@ -190,6 +244,9 @@ module.exports = Mn.View.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Certificates
|
// Certificates
|
||||||
|
this.ui.le_error_info.hide();
|
||||||
|
this.ui.dns_challenge_content.hide();
|
||||||
|
this.ui.credentials_file_content.hide();
|
||||||
this.ui.letsencrypt.hide();
|
this.ui.letsencrypt.hide();
|
||||||
this.ui.certificate_select.selectize({
|
this.ui.certificate_select.selectize({
|
||||||
valueField: 'id',
|
valueField: 'id',
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
<button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button>
|
<button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body has-tabs">
|
<div class="modal-body has-tabs">
|
||||||
|
<div class="alert alert-danger mb-0 rounded-0" id="le-error-info" role="alert"></div>
|
||||||
<form>
|
<form>
|
||||||
<ul class="nav nav-tabs" role="tablist">
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
<li role="presentation" class="nav-item"><a href="#details" aria-controls="tab1" role="tab" data-toggle="tab" class="nav-link active"><i class="fe fe-zap"></i> <%- i18n('all-hosts', 'details') %></a></li>
|
<li role="presentation" class="nav-item"><a href="#details" aria-controls="tab1" role="tab" data-toggle="tab" class="nav-link active"><i class="fe fe-zap"></i> <%- i18n('all-hosts', 'details') %></a></li>
|
||||||
@ -141,21 +142,96 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- CloudFlare -->
|
<!-- DNS challenge -->
|
||||||
<div class="col-sm-12 col-md-12 letsencrypt">
|
<div class="col-sm-12 col-md-12 letsencrypt">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="custom-switch">
|
<label class="custom-switch">
|
||||||
<input type="checkbox" class="custom-switch-input" name="meta[cloudflare_use]" value="1">
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
class="custom-switch-input"
|
||||||
|
name="meta[dns_challenge]"
|
||||||
|
value="1"
|
||||||
|
<%- getUseDnsChallenge() ? 'checked' : '' %>
|
||||||
|
>
|
||||||
<span class="custom-switch-indicator"></span>
|
<span class="custom-switch-indicator"></span>
|
||||||
<span class="custom-switch-description"><%= i18n('ssl', 'use-cloudflare') %></span>
|
<span class="custom-switch-description"><%= i18n('ssl', 'dns-challenge') %></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12 col-md-12 cloudflare letsencrypt">
|
<div class="col-sm-12 col-md-12 letsencrypt">
|
||||||
<div class="form-group">
|
<fieldset class="form-fieldset dns-challenge">
|
||||||
<label class="form-label">CloudFlare DNS API Token <span class="form-required">*</span></label>
|
<div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('ssl', 'certbot-warning') %></div>
|
||||||
<input type="text" name="meta[cloudflare_token]" class="form-control" id="cloudflare_token">
|
|
||||||
</div>
|
<!-- Certbot DNS plugin selection -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label"><%- i18n('ssl', 'dns-provider') %> <span class="form-required">*</span></label>
|
||||||
|
<select
|
||||||
|
name="meta[dns_provider]"
|
||||||
|
id="dns_provider"
|
||||||
|
class="form-control custom-select"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
value=""
|
||||||
|
disabled
|
||||||
|
hidden
|
||||||
|
<%- getDnsProvider() === null ? 'selected' : '' %>
|
||||||
|
>Please Choose...</option>
|
||||||
|
<% _.each(dns_plugins, function(plugin_info, plugin_name){ %>
|
||||||
|
<option
|
||||||
|
value="<%- plugin_name %>"
|
||||||
|
<%- getDnsProvider() === plugin_name ? 'selected' : '' %>
|
||||||
|
><%- plugin_info.display_name %></option>
|
||||||
|
<% }); %>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Certbot credentials file content -->
|
||||||
|
<div class="row credentials-file-content">
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label"><%- i18n('ssl', 'credentials-file-content') %> <span class="form-required">*</span></label>
|
||||||
|
<textarea
|
||||||
|
name="meta[dns_provider_credentials]"
|
||||||
|
class="form-control text-monospace"
|
||||||
|
id="dns_provider_credentials"
|
||||||
|
><%- getDnsProviderCredentials() %></textarea>
|
||||||
|
<div class="text-secondary small">
|
||||||
|
<i class="fe fe-info"></i>
|
||||||
|
<%= i18n('ssl', 'credentials-file-content-info') %>
|
||||||
|
</div>
|
||||||
|
<div class="text-red small">
|
||||||
|
<i class="fe fe-alert-triangle"></i>
|
||||||
|
<%= i18n('ssl', 'stored-as-plaintext-info') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- DNS propagation delay -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group mb-0">
|
||||||
|
<label class="form-label"><%- i18n('ssl', 'propagation-seconds') %></label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
name="meta[propagation_seconds]"
|
||||||
|
class="form-control"
|
||||||
|
id="propagation_seconds"
|
||||||
|
value="<%- getPropagationSeconds() %>"
|
||||||
|
>
|
||||||
|
<div class="text-secondary small">
|
||||||
|
<i class="fe fe-info"></i>
|
||||||
|
<%= i18n('ssl', 'propagation-seconds-info') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Lets encrypt -->
|
<!-- Lets encrypt -->
|
||||||
|
@ -7,6 +7,8 @@ const certListItemTemplate = require('../certificates-list-item.ejs');
|
|||||||
const accessListItemTemplate = require('./access-list-item.ejs');
|
const accessListItemTemplate = require('./access-list-item.ejs');
|
||||||
const CustomLocation = require('./location');
|
const CustomLocation = require('./location');
|
||||||
const Helpers = require('../../../lib/helpers');
|
const Helpers = require('../../../lib/helpers');
|
||||||
|
const i18n = require('../../i18n');
|
||||||
|
const dns_providers = require('../../../../../global/certbot-dns-plugins');
|
||||||
|
|
||||||
|
|
||||||
require('jquery-serializejson');
|
require('jquery-serializejson');
|
||||||
@ -19,25 +21,29 @@ module.exports = Mn.View.extend({
|
|||||||
locationsCollection: new ProxyLocationModel.Collection(),
|
locationsCollection: new ProxyLocationModel.Collection(),
|
||||||
|
|
||||||
ui: {
|
ui: {
|
||||||
form: 'form',
|
form: 'form',
|
||||||
domain_names: 'input[name="domain_names"]',
|
domain_names: 'input[name="domain_names"]',
|
||||||
forward_host: 'input[name="forward_host"]',
|
forward_host: 'input[name="forward_host"]',
|
||||||
buttons: '.modal-footer button',
|
buttons: '.modal-footer button',
|
||||||
cancel: 'button.cancel',
|
cancel: 'button.cancel',
|
||||||
save: 'button.save',
|
save: 'button.save',
|
||||||
add_location_btn: 'button.add_location',
|
add_location_btn: 'button.add_location',
|
||||||
locations_container:'.locations_container',
|
locations_container: '.locations_container',
|
||||||
certificate_select: 'select[name="certificate_id"]',
|
le_error_info: '#le-error-info',
|
||||||
access_list_select: 'select[name="access_list_id"]',
|
certificate_select: 'select[name="certificate_id"]',
|
||||||
ssl_forced: 'input[name="ssl_forced"]',
|
access_list_select: 'select[name="access_list_id"]',
|
||||||
hsts_enabled: 'input[name="hsts_enabled"]',
|
ssl_forced: 'input[name="ssl_forced"]',
|
||||||
hsts_subdomains: 'input[name="hsts_subdomains"]',
|
hsts_enabled: 'input[name="hsts_enabled"]',
|
||||||
http2_support: 'input[name="http2_support"]',
|
hsts_subdomains: 'input[name="hsts_subdomains"]',
|
||||||
cloudflare_switch: 'input[name="meta[cloudflare_use]"]',
|
http2_support: 'input[name="http2_support"]',
|
||||||
cloudflare_token: 'input[name="meta[cloudflare_token]"',
|
dns_challenge_switch: 'input[name="meta[dns_challenge]"]',
|
||||||
cloudflare: '.cloudflare',
|
dns_challenge_content: '.dns-challenge',
|
||||||
forward_scheme: 'select[name="forward_scheme"]',
|
dns_provider: 'select[name="meta[dns_provider]"]',
|
||||||
letsencrypt: '.letsencrypt'
|
credentials_file_content: '.credentials-file-content',
|
||||||
|
dns_provider_credentials: 'textarea[name="meta[dns_provider_credentials]"]',
|
||||||
|
propagation_seconds: 'input[name="meta[propagation_seconds]"]',
|
||||||
|
forward_scheme: 'select[name="forward_scheme"]',
|
||||||
|
letsencrypt: '.letsencrypt'
|
||||||
},
|
},
|
||||||
|
|
||||||
regions: {
|
regions: {
|
||||||
@ -49,7 +55,7 @@ module.exports = Mn.View.extend({
|
|||||||
let id = this.ui.certificate_select.val();
|
let id = this.ui.certificate_select.val();
|
||||||
if (id === 'new') {
|
if (id === 'new') {
|
||||||
this.ui.letsencrypt.show().find('input').prop('disabled', false);
|
this.ui.letsencrypt.show().find('input').prop('disabled', false);
|
||||||
this.ui.cloudflare.hide();
|
this.ui.dns_challenge_content.hide();
|
||||||
} else {
|
} else {
|
||||||
this.ui.letsencrypt.hide().find('input').prop('disabled', true);
|
this.ui.letsencrypt.hide().find('input').prop('disabled', true);
|
||||||
}
|
}
|
||||||
@ -95,14 +101,31 @@ module.exports = Mn.View.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'change @ui.cloudflare_switch': function() {
|
'change @ui.dns_challenge_switch': function () {
|
||||||
let checked = this.ui.cloudflare_switch.prop('checked');
|
const checked = this.ui.dns_challenge_switch.prop('checked');
|
||||||
if (checked) {
|
if (checked) {
|
||||||
this.ui.cloudflare_token.prop('required', 'required');
|
this.ui.dns_provider.prop('required', 'required');
|
||||||
this.ui.cloudflare.show();
|
const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value;
|
||||||
} else {
|
if(selected_provider != '' && dns_providers[selected_provider].credentials !== false){
|
||||||
this.ui.cloudflare_token.prop('required', false);
|
this.ui.dns_provider_credentials.prop('required', 'required');
|
||||||
this.ui.cloudflare.hide();
|
}
|
||||||
|
this.ui.dns_challenge_content.show();
|
||||||
|
} else {
|
||||||
|
this.ui.dns_provider.prop('required', false);
|
||||||
|
this.ui.dns_provider_credentials.prop('required', false);
|
||||||
|
this.ui.dns_challenge_content.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'change @ui.dns_provider': function () {
|
||||||
|
const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value;
|
||||||
|
if (selected_provider != '' && dns_providers[selected_provider].credentials !== false) {
|
||||||
|
this.ui.dns_provider_credentials.prop('required', 'required');
|
||||||
|
this.ui.dns_provider_credentials[0].value = dns_providers[selected_provider].credentials;
|
||||||
|
this.ui.credentials_file_content.show();
|
||||||
|
} else {
|
||||||
|
this.ui.dns_provider_credentials.prop('required', false);
|
||||||
|
this.ui.credentials_file_content.hide();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -115,6 +138,7 @@ module.exports = Mn.View.extend({
|
|||||||
|
|
||||||
'click @ui.save': function (e) {
|
'click @ui.save': function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
this.ui.le_error_info.hide();
|
||||||
|
|
||||||
if (!this.ui.form[0].checkValidity()) {
|
if (!this.ui.form[0].checkValidity()) {
|
||||||
$('<input type="submit">').hide().appendTo(this.ui.form).click().remove();
|
$('<input type="submit">').hide().appendTo(this.ui.form).click().remove();
|
||||||
@ -143,6 +167,18 @@ module.exports = Mn.View.extend({
|
|||||||
data.hsts_enabled = !!data.hsts_enabled;
|
data.hsts_enabled = !!data.hsts_enabled;
|
||||||
data.hsts_subdomains = !!data.hsts_subdomains;
|
data.hsts_subdomains = !!data.hsts_subdomains;
|
||||||
data.ssl_forced = !!data.ssl_forced;
|
data.ssl_forced = !!data.ssl_forced;
|
||||||
|
|
||||||
|
if (typeof data.meta === 'undefined') data.meta = {};
|
||||||
|
data.meta.letsencrypt_agree = data.meta.letsencrypt_agree == 1;
|
||||||
|
data.meta.dns_challenge = data.meta.dns_challenge == 1;
|
||||||
|
|
||||||
|
if(!data.meta.dns_challenge){
|
||||||
|
data.meta.dns_provider = undefined;
|
||||||
|
data.meta.dns_provider_credentials = undefined;
|
||||||
|
data.meta.propagation_seconds = undefined;
|
||||||
|
} else {
|
||||||
|
if(data.meta.propagation_seconds === '') data.meta.propagation_seconds = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof data.domain_names === 'string' && data.domain_names) {
|
if (typeof data.domain_names === 'string' && data.domain_names) {
|
||||||
data.domain_names = data.domain_names.split(',');
|
data.domain_names = data.domain_names.split(',');
|
||||||
@ -151,7 +187,7 @@ module.exports = Mn.View.extend({
|
|||||||
// Check for any domain names containing wildcards, which are not allowed with letsencrypt
|
// Check for any domain names containing wildcards, which are not allowed with letsencrypt
|
||||||
if (data.certificate_id === 'new') {
|
if (data.certificate_id === 'new') {
|
||||||
let domain_err = false;
|
let domain_err = false;
|
||||||
if (!data.meta.cloudflare_use) {
|
if (!data.meta.dns_challenge) {
|
||||||
data.domain_names.map(function (name) {
|
data.domain_names.map(function (name) {
|
||||||
if (name.match(/\*/im)) {
|
if (name.match(/\*/im)) {
|
||||||
domain_err = true;
|
domain_err = true;
|
||||||
@ -160,12 +196,9 @@ module.exports = Mn.View.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (domain_err) {
|
if (domain_err) {
|
||||||
alert('Cannot request Let\'s Encrypt Certificate for wildcard domains without CloudFlare DNS.');
|
alert(i18n('ssl', 'no-wildcard-without-dns'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.meta.cloudflare_use = data.meta.cloudflare_use === '1';
|
|
||||||
data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';
|
|
||||||
} else {
|
} else {
|
||||||
data.certificate_id = parseInt(data.certificate_id, 10);
|
data.certificate_id = parseInt(data.certificate_id, 10);
|
||||||
}
|
}
|
||||||
@ -194,7 +227,15 @@ module.exports = Mn.View.extend({
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
alert(err.message);
|
let more_info = '';
|
||||||
|
if(err.code === 500 && err.debug){
|
||||||
|
try{
|
||||||
|
more_info = JSON.parse(err.debug).debug.stack.join("\n");
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
this.ui.le_error_info[0].innerHTML = `${err.message}${more_info !== '' ? `<pre class="mt-3">${more_info}</pre>`:''}`;
|
||||||
|
this.ui.le_error_info.show();
|
||||||
|
this.ui.le_error_info[0].scrollIntoView();
|
||||||
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
|
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
|
||||||
this.ui.save.removeClass('btn-loading');
|
this.ui.save.removeClass('btn-loading');
|
||||||
});
|
});
|
||||||
@ -204,7 +245,20 @@ module.exports = Mn.View.extend({
|
|||||||
templateContext: {
|
templateContext: {
|
||||||
getLetsencryptEmail: function () {
|
getLetsencryptEmail: function () {
|
||||||
return App.Cache.User.get('email');
|
return App.Cache.User.get('email');
|
||||||
}
|
},
|
||||||
|
getUseDnsChallenge: function () {
|
||||||
|
return typeof this.meta.dns_challenge !== 'undefined' ? this.meta.dns_challenge : false;
|
||||||
|
},
|
||||||
|
getDnsProvider: function () {
|
||||||
|
return typeof this.meta.dns_provider !== 'undefined' && this.meta.dns_provider != '' ? this.meta.dns_provider : null;
|
||||||
|
},
|
||||||
|
getDnsProviderCredentials: function () {
|
||||||
|
return typeof this.meta.dns_provider_credentials !== 'undefined' ? this.meta.dns_provider_credentials : '';
|
||||||
|
},
|
||||||
|
getPropagationSeconds: function () {
|
||||||
|
return typeof this.meta.propagation_seconds !== 'undefined' ? this.meta.propagation_seconds : '';
|
||||||
|
},
|
||||||
|
dns_plugins: dns_providers,
|
||||||
},
|
},
|
||||||
|
|
||||||
onRender: function () {
|
onRender: function () {
|
||||||
@ -258,6 +312,9 @@ module.exports = Mn.View.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Certificates
|
// Certificates
|
||||||
|
this.ui.le_error_info.hide();
|
||||||
|
this.ui.dns_challenge_content.hide();
|
||||||
|
this.ui.credentials_file_content.hide();
|
||||||
this.ui.letsencrypt.hide();
|
this.ui.letsencrypt.hide();
|
||||||
this.ui.certificate_select.selectize({
|
this.ui.certificate_select.selectize({
|
||||||
valueField: 'id',
|
valueField: 'id',
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
<button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button>
|
<button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body has-tabs">
|
<div class="modal-body has-tabs">
|
||||||
|
<div class="alert alert-danger mb-0 rounded-0" id="le-error-info" role="alert"></div>
|
||||||
<form>
|
<form>
|
||||||
<ul class="nav nav-tabs" role="tablist">
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
<li role="presentation" class="nav-item"><a href="#details" aria-controls="tab1" role="tab" data-toggle="tab" class="nav-link active"><i class="fe fe-zap"></i> <%- i18n('all-hosts', 'details') %></a></li>
|
<li role="presentation" class="nav-item"><a href="#details" aria-controls="tab1" role="tab" data-toggle="tab" class="nav-link active"><i class="fe fe-zap"></i> <%- i18n('all-hosts', 'details') %></a></li>
|
||||||
@ -21,12 +22,35 @@
|
|||||||
<input type="text" name="domain_names" class="form-control" id="input-domains" value="<%- domain_names.join(',') %>" required>
|
<input type="text" name="domain_names" class="form-control" id="input-domains" value="<%- domain_names.join(',') %>" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12 col-md-12">
|
<div class="col-sm-3 col-md-3">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label"><%- i18n('redirection-hosts', 'forward-scheme') %><span class="form-required">*</span></label>
|
||||||
|
<select name="forward_scheme" class="form-control custom-select" placeholder="$scheme">
|
||||||
|
<option value="$scheme" <%- forward_scheme === '$scheme' ? 'selected' : '' %>>auto</option>
|
||||||
|
<option value="http" <%- forward_scheme === 'http' ? 'selected' : '' %>>http</option>
|
||||||
|
<option value="https" <%- forward_scheme === 'https' ? 'selected' : '' %>>https</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-9 col-md-9">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label"><%- i18n('redirection-hosts', 'forward-domain') %><span class="form-required">*</span></label>
|
<label class="form-label"><%- i18n('redirection-hosts', 'forward-domain') %><span class="form-required">*</span></label>
|
||||||
<input type="text" name="forward_domain_name" class="form-control text-monospace" placeholder="" value="<%- forward_domain_name %>" required>
|
<input type="text" name="forward_domain_name" class="form-control text-monospace" placeholder="" value="<%- forward_domain_name %>" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label"><%- i18n('redirection-hosts', 'forward-http-status-code') %><span class="form-required">*</span></label>
|
||||||
|
<select name="forward_http_code" class="form-control custom-select" placeholder="301">
|
||||||
|
<option value="300" <%- forward_http_code == '300' ? 'selected' : '' %>>300 Multiple choices</option>
|
||||||
|
<option value="301" <%- forward_http_code == '301' ? 'selected' : '' %>>301 Moved permanently</option>
|
||||||
|
<option value="302" <%- forward_http_code == '302' ? 'selected' : '' %>>302 Found</option>
|
||||||
|
<option value="303" <%- forward_http_code == '303' ? 'selected' : '' %>>303 See other</option>
|
||||||
|
<option value="307" <%- forward_http_code == '307' ? 'selected' : '' %>>307 Temporary redirect</option>
|
||||||
|
<option value="308" <%- forward_http_code == '308' ? 'selected' : '' %>>308 Permanent redirect</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="col-sm-6 col-md-6">
|
<div class="col-sm-6 col-md-6">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="custom-switch">
|
<label class="custom-switch">
|
||||||
@ -97,21 +121,96 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- CloudFlare -->
|
<!-- DNS challenge -->
|
||||||
<div class="col-sm-12 col-md-12 letsencrypt">
|
<div class="col-sm-12 col-md-12 letsencrypt">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="custom-switch">
|
<label class="custom-switch">
|
||||||
<input type="checkbox" class="custom-switch-input" name="meta[cloudflare_use]" value="1">
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
class="custom-switch-input"
|
||||||
|
name="meta[dns_challenge]"
|
||||||
|
value="1"
|
||||||
|
<%- getUseDnsChallenge() ? 'checked' : '' %>
|
||||||
|
>
|
||||||
<span class="custom-switch-indicator"></span>
|
<span class="custom-switch-indicator"></span>
|
||||||
<span class="custom-switch-description"><%= i18n('ssl', 'use-cloudflare') %></span>
|
<span class="custom-switch-description"><%= i18n('ssl', 'dns-challenge') %></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12 col-md-12 cloudflare letsencrypt">
|
<div class="col-sm-12 col-md-12 letsencrypt">
|
||||||
<div class="form-group">
|
<fieldset class="form-fieldset dns-challenge">
|
||||||
<label class="form-label">CloudFlare DNS API Token <span class="form-required">*</span></label>
|
<div class="text-red mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('ssl', 'certbot-warning') %></div>
|
||||||
<input type="text" name="meta[cloudflare_token]" class="form-control" id="cloudflare_token">
|
|
||||||
</div>
|
<!-- Certbot DNS plugin selection -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label"><%- i18n('ssl', 'dns-provider') %> <span class="form-required">*</span></label>
|
||||||
|
<select
|
||||||
|
name="meta[dns_provider]"
|
||||||
|
id="dns_provider"
|
||||||
|
class="form-control custom-select"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
value=""
|
||||||
|
disabled
|
||||||
|
hidden
|
||||||
|
<%- getDnsProvider() === null ? 'selected' : '' %>
|
||||||
|
>Please Choose...</option>
|
||||||
|
<% _.each(dns_plugins, function(plugin_info, plugin_name){ %>
|
||||||
|
<option
|
||||||
|
value="<%- plugin_name %>"
|
||||||
|
<%- getDnsProvider() === plugin_name ? 'selected' : '' %>
|
||||||
|
><%- plugin_info.display_name %></option>
|
||||||
|
<% }); %>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Certbot credentials file content -->
|
||||||
|
<div class="row credentials-file-content">
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label"><%- i18n('ssl', 'credentials-file-content') %> <span class="form-required">*</span></label>
|
||||||
|
<textarea
|
||||||
|
name="meta[dns_provider_credentials]"
|
||||||
|
class="form-control text-monospace"
|
||||||
|
id="dns_provider_credentials"
|
||||||
|
><%- getDnsProviderCredentials() %></textarea>
|
||||||
|
<div class="text-secondary small">
|
||||||
|
<i class="fe fe-info"></i>
|
||||||
|
<%= i18n('ssl', 'credentials-file-content-info') %>
|
||||||
|
</div>
|
||||||
|
<div class="text-red small">
|
||||||
|
<i class="fe fe-alert-triangle"></i>
|
||||||
|
<%= i18n('ssl', 'stored-as-plaintext-info') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- DNS propagation delay -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group mb-0">
|
||||||
|
<label class="form-label"><%- i18n('ssl', 'propagation-seconds') %></label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
name="meta[propagation_seconds]"
|
||||||
|
class="form-control"
|
||||||
|
id="propagation_seconds"
|
||||||
|
value="<%- getPropagationSeconds() %>"
|
||||||
|
>
|
||||||
|
<div class="text-secondary small">
|
||||||
|
<i class="fe fe-info"></i>
|
||||||
|
<%= i18n('ssl', 'propagation-seconds-info') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Lets encrypt -->
|
<!-- Lets encrypt -->
|
||||||
|
@ -4,6 +4,9 @@ const RedirectionHostModel = require('../../../models/redirection-host');
|
|||||||
const template = require('./form.ejs');
|
const template = require('./form.ejs');
|
||||||
const certListItemTemplate = require('../certificates-list-item.ejs');
|
const certListItemTemplate = require('../certificates-list-item.ejs');
|
||||||
const Helpers = require('../../../lib/helpers');
|
const Helpers = require('../../../lib/helpers');
|
||||||
|
const i18n = require('../../i18n');
|
||||||
|
const dns_providers = require('../../../../../global/certbot-dns-plugins');
|
||||||
|
|
||||||
|
|
||||||
require('jquery-serializejson');
|
require('jquery-serializejson');
|
||||||
require('selectize');
|
require('selectize');
|
||||||
@ -13,20 +16,24 @@ module.exports = Mn.View.extend({
|
|||||||
className: 'modal-dialog',
|
className: 'modal-dialog',
|
||||||
|
|
||||||
ui: {
|
ui: {
|
||||||
form: 'form',
|
form: 'form',
|
||||||
domain_names: 'input[name="domain_names"]',
|
domain_names: 'input[name="domain_names"]',
|
||||||
buttons: '.modal-footer button',
|
buttons: '.modal-footer button',
|
||||||
cancel: 'button.cancel',
|
cancel: 'button.cancel',
|
||||||
save: 'button.save',
|
save: 'button.save',
|
||||||
certificate_select: 'select[name="certificate_id"]',
|
le_error_info: '#le-error-info',
|
||||||
ssl_forced: 'input[name="ssl_forced"]',
|
certificate_select: 'select[name="certificate_id"]',
|
||||||
hsts_enabled: 'input[name="hsts_enabled"]',
|
ssl_forced: 'input[name="ssl_forced"]',
|
||||||
hsts_subdomains: 'input[name="hsts_subdomains"]',
|
hsts_enabled: 'input[name="hsts_enabled"]',
|
||||||
http2_support: 'input[name="http2_support"]',
|
hsts_subdomains: 'input[name="hsts_subdomains"]',
|
||||||
cloudflare_switch: 'input[name="meta[cloudflare_use]"]',
|
http2_support: 'input[name="http2_support"]',
|
||||||
cloudflare_token: 'input[name="meta[cloudflare_token]"',
|
dns_challenge_switch: 'input[name="meta[dns_challenge]"]',
|
||||||
cloudflare: '.cloudflare',
|
dns_challenge_content: '.dns-challenge',
|
||||||
letsencrypt: '.letsencrypt'
|
dns_provider: 'select[name="meta[dns_provider]"]',
|
||||||
|
credentials_file_content: '.credentials-file-content',
|
||||||
|
dns_provider_credentials: 'textarea[name="meta[dns_provider_credentials]"]',
|
||||||
|
propagation_seconds: 'input[name="meta[propagation_seconds]"]',
|
||||||
|
letsencrypt: '.letsencrypt'
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
@ -34,7 +41,7 @@ module.exports = Mn.View.extend({
|
|||||||
let id = this.ui.certificate_select.val();
|
let id = this.ui.certificate_select.val();
|
||||||
if (id === 'new') {
|
if (id === 'new') {
|
||||||
this.ui.letsencrypt.show().find('input').prop('disabled', false);
|
this.ui.letsencrypt.show().find('input').prop('disabled', false);
|
||||||
this.ui.cloudflare.hide();
|
this.ui.dns_challenge_content.hide();
|
||||||
} else {
|
} else {
|
||||||
this.ui.letsencrypt.hide().find('input').prop('disabled', true);
|
this.ui.letsencrypt.hide().find('input').prop('disabled', true);
|
||||||
}
|
}
|
||||||
@ -80,19 +87,37 @@ module.exports = Mn.View.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'change @ui.cloudflare_switch': function() {
|
'change @ui.dns_challenge_switch': function () {
|
||||||
let checked = this.ui.cloudflare_switch.prop('checked');
|
const checked = this.ui.dns_challenge_switch.prop('checked');
|
||||||
if (checked) {
|
if (checked) {
|
||||||
this.ui.cloudflare_token.prop('required', 'required');
|
this.ui.dns_provider.prop('required', 'required');
|
||||||
this.ui.cloudflare.show();
|
const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value;
|
||||||
} else {
|
if(selected_provider != '' && dns_providers[selected_provider].credentials !== false){
|
||||||
this.ui.cloudflare_token.prop('required', false);
|
this.ui.dns_provider_credentials.prop('required', 'required');
|
||||||
this.ui.cloudflare.hide();
|
}
|
||||||
|
this.ui.dns_challenge_content.show();
|
||||||
|
} else {
|
||||||
|
this.ui.dns_provider.prop('required', false);
|
||||||
|
this.ui.dns_provider_credentials.prop('required', false);
|
||||||
|
this.ui.dns_challenge_content.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'change @ui.dns_provider': function () {
|
||||||
|
const selected_provider = this.ui.dns_provider[0].options[this.ui.dns_provider[0].selectedIndex].value;
|
||||||
|
if (selected_provider != '' && dns_providers[selected_provider].credentials !== false) {
|
||||||
|
this.ui.dns_provider_credentials.prop('required', 'required');
|
||||||
|
this.ui.dns_provider_credentials[0].value = dns_providers[selected_provider].credentials;
|
||||||
|
this.ui.credentials_file_content.show();
|
||||||
|
} else {
|
||||||
|
this.ui.dns_provider_credentials.prop('required', false);
|
||||||
|
this.ui.credentials_file_content.hide();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'click @ui.save': function (e) {
|
'click @ui.save': function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
this.ui.le_error_info.hide();
|
||||||
|
|
||||||
if (!this.ui.form[0].checkValidity()) {
|
if (!this.ui.form[0].checkValidity()) {
|
||||||
$('<input type="submit">').hide().appendTo(this.ui.form).click().remove();
|
$('<input type="submit">').hide().appendTo(this.ui.form).click().remove();
|
||||||
@ -103,12 +128,24 @@ module.exports = Mn.View.extend({
|
|||||||
let data = this.ui.form.serializeJSON();
|
let data = this.ui.form.serializeJSON();
|
||||||
|
|
||||||
// Manipulate
|
// Manipulate
|
||||||
data.block_exploits = !!data.block_exploits;
|
data.block_exploits = !!data.block_exploits;
|
||||||
data.preserve_path = !!data.preserve_path;
|
data.preserve_path = !!data.preserve_path;
|
||||||
data.http2_support = !!data.http2_support;
|
data.http2_support = !!data.http2_support;
|
||||||
data.hsts_enabled = !!data.hsts_enabled;
|
data.hsts_enabled = !!data.hsts_enabled;
|
||||||
data.hsts_subdomains = !!data.hsts_subdomains;
|
data.hsts_subdomains = !!data.hsts_subdomains;
|
||||||
data.ssl_forced = !!data.ssl_forced;
|
data.ssl_forced = !!data.ssl_forced;
|
||||||
|
|
||||||
|
if (typeof data.meta === 'undefined') data.meta = {};
|
||||||
|
data.meta.letsencrypt_agree = data.meta.letsencrypt_agree == 1;
|
||||||
|
data.meta.dns_challenge = data.meta.dns_challenge == 1;
|
||||||
|
|
||||||
|
if(!data.meta.dns_challenge){
|
||||||
|
data.meta.dns_provider = undefined;
|
||||||
|
data.meta.dns_provider_credentials = undefined;
|
||||||
|
data.meta.propagation_seconds = undefined;
|
||||||
|
} else {
|
||||||
|
if(data.meta.propagation_seconds === '') data.meta.propagation_seconds = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof data.domain_names === 'string' && data.domain_names) {
|
if (typeof data.domain_names === 'string' && data.domain_names) {
|
||||||
data.domain_names = data.domain_names.split(',');
|
data.domain_names = data.domain_names.split(',');
|
||||||
@ -117,7 +154,7 @@ module.exports = Mn.View.extend({
|
|||||||
// Check for any domain names containing wildcards, which are not allowed with letsencrypt
|
// Check for any domain names containing wildcards, which are not allowed with letsencrypt
|
||||||
if (data.certificate_id === 'new') {
|
if (data.certificate_id === 'new') {
|
||||||
let domain_err = false;
|
let domain_err = false;
|
||||||
if (!data.meta.cloudflare_use) {
|
if (!data.meta.dns_challenge) {
|
||||||
data.domain_names.map(function (name) {
|
data.domain_names.map(function (name) {
|
||||||
if (name.match(/\*/im)) {
|
if (name.match(/\*/im)) {
|
||||||
domain_err = true;
|
domain_err = true;
|
||||||
@ -126,12 +163,9 @@ module.exports = Mn.View.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (domain_err) {
|
if (domain_err) {
|
||||||
alert('Cannot request Let\'s Encrypt Certificate for wildcard domains without CloudFlare DNS.');
|
alert(i18n('ssl', 'no-wildcard-without-dns'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.meta.cloudflare_use = data.meta.cloudflare_use === '1';
|
|
||||||
data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';
|
|
||||||
} else {
|
} else {
|
||||||
data.certificate_id = parseInt(data.certificate_id, 10);
|
data.certificate_id = parseInt(data.certificate_id, 10);
|
||||||
}
|
}
|
||||||
@ -160,7 +194,15 @@ module.exports = Mn.View.extend({
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
alert(err.message);
|
let more_info = '';
|
||||||
|
if(err.code === 500 && err.debug){
|
||||||
|
try{
|
||||||
|
more_info = JSON.parse(err.debug).debug.stack.join("\n");
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
this.ui.le_error_info[0].innerHTML = `${err.message}${more_info !== '' ? `<pre class="mt-3">${more_info}</pre>`:''}`;
|
||||||
|
this.ui.le_error_info.show();
|
||||||
|
this.ui.le_error_info[0].scrollIntoView();
|
||||||
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
|
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
|
||||||
this.ui.save.removeClass('btn-loading');
|
this.ui.save.removeClass('btn-loading');
|
||||||
});
|
});
|
||||||
@ -170,7 +212,20 @@ module.exports = Mn.View.extend({
|
|||||||
templateContext: {
|
templateContext: {
|
||||||
getLetsencryptEmail: function () {
|
getLetsencryptEmail: function () {
|
||||||
return App.Cache.User.get('email');
|
return App.Cache.User.get('email');
|
||||||
}
|
},
|
||||||
|
getUseDnsChallenge: function () {
|
||||||
|
return typeof this.meta.dns_challenge !== 'undefined' ? this.meta.dns_challenge : false;
|
||||||
|
},
|
||||||
|
getDnsProvider: function () {
|
||||||
|
return typeof this.meta.dns_provider !== 'undefined' && this.meta.dns_provider != '' ? this.meta.dns_provider : null;
|
||||||
|
},
|
||||||
|
getDnsProviderCredentials: function () {
|
||||||
|
return typeof this.meta.dns_provider_credentials !== 'undefined' ? this.meta.dns_provider_credentials : '';
|
||||||
|
},
|
||||||
|
getPropagationSeconds: function () {
|
||||||
|
return typeof this.meta.propagation_seconds !== 'undefined' ? this.meta.propagation_seconds : '';
|
||||||
|
},
|
||||||
|
dns_plugins: dns_providers,
|
||||||
},
|
},
|
||||||
|
|
||||||
onRender: function () {
|
onRender: function () {
|
||||||
@ -191,6 +246,9 @@ module.exports = Mn.View.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Certificates
|
// Certificates
|
||||||
|
this.ui.le_error_info.hide();
|
||||||
|
this.ui.dns_challenge_content.hide();
|
||||||
|
this.ui.credentials_file_content.hide();
|
||||||
this.ui.letsencrypt.hide();
|
this.ui.letsencrypt.hide();
|
||||||
this.ui.certificate_select.selectize({
|
this.ui.certificate_select.selectize({
|
||||||
valueField: 'id',
|
valueField: 'id',
|
||||||
|
@ -22,6 +22,12 @@
|
|||||||
<%- i18n('str', 'created-on', {date: formatDbDate(created_on, 'Do MMMM YYYY')}) %>
|
<%- i18n('str', 'created-on', {date: formatDbDate(created_on, 'Do MMMM YYYY')}) %>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="text-monospace"><%- forward_http_code %></div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="text-monospace"><%- forward_scheme == '$scheme' ? 'auto' : forward_scheme %></div>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="text-monospace"><%- forward_domain_name %></div>
|
<div class="text-monospace"><%- forward_domain_name %></div>
|
||||||
</td>
|
</td>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<th width="30"> </th>
|
<th width="30"> </th>
|
||||||
<th><%- i18n('str', 'source') %></th>
|
<th><%- i18n('str', 'source') %></th>
|
||||||
|
<th><%- i18n('redirection-hosts', 'forward-http-status-code') %></th>
|
||||||
|
<th><%- i18n('redirection-hosts', 'forward-scheme') %></th>
|
||||||
<th><%- i18n('str', 'destination') %></th>
|
<th><%- i18n('str', 'destination') %></th>
|
||||||
<th><%- i18n('str', 'ssl') %></th>
|
<th><%- i18n('str', 'ssl') %></th>
|
||||||
<th><%- i18n('str', 'status') %></th>
|
<th><%- i18n('str', 'status') %></th>
|
||||||
|
@ -102,7 +102,18 @@
|
|||||||
"letsencrypt-agree": "I Agree to the <a href=\"{url}\" target=\"_blank\">Let's Encrypt Terms of Service</a>",
|
"letsencrypt-agree": "I Agree to the <a href=\"{url}\" target=\"_blank\">Let's Encrypt Terms of Service</a>",
|
||||||
"delete-ssl": "The SSL certificates attached will NOT be removed, they will need to be removed manually.",
|
"delete-ssl": "The SSL certificates attached will NOT be removed, they will need to be removed manually.",
|
||||||
"hosts-warning": "These domains must be already configured to point to this installation",
|
"hosts-warning": "These domains must be already configured to point to this installation",
|
||||||
"use-cloudflare": "Use CloudFlare DNS verification"
|
"no-wildcard-without-dns": "Cannot request Let's Encrypt Certificate for wildcard domains when not using DNS challenge",
|
||||||
|
"dns-challenge": "Use a DNS Challenge",
|
||||||
|
"certbot-warning": "This section requires some knowledge about Certbot and its DNS plugins. Please consult the respective plugins documentation.",
|
||||||
|
"dns-provider": "DNS Provider",
|
||||||
|
"please-choose": "Please Choose...",
|
||||||
|
"credentials-file-content": "Credentials File Content",
|
||||||
|
"credentials-file-content-info": "This plugin requires a configuration file containing an API token or other credentials to your provider",
|
||||||
|
"stored-as-plaintext-info": "This data will be stored as plaintext in the database and in a file!",
|
||||||
|
"propagation-seconds": "Propagation Seconds",
|
||||||
|
"propagation-seconds-info": "Leave empty to use the plugins default value. Number of seconds to wait for DNS propagation.",
|
||||||
|
"processing-info": "Processing... This might take a few minutes.",
|
||||||
|
"passphrase-protection-support-info": "Key files protected with a passphrase are not supported."
|
||||||
},
|
},
|
||||||
"proxy-hosts": {
|
"proxy-hosts": {
|
||||||
"title": "Proxy Hosts",
|
"title": "Proxy Hosts",
|
||||||
@ -126,6 +137,8 @@
|
|||||||
"empty": "There are no Redirection Hosts",
|
"empty": "There are no Redirection Hosts",
|
||||||
"add": "Add Redirection Host",
|
"add": "Add Redirection Host",
|
||||||
"form-title": "{id, select, undefined{New} other{Edit}} Redirection Host",
|
"form-title": "{id, select, undefined{New} other{Edit}} Redirection Host",
|
||||||
|
"forward-scheme": "Scheme",
|
||||||
|
"forward-http-status-code": "HTTP Code",
|
||||||
"forward-domain": "Forward Domain",
|
"forward-domain": "Forward Domain",
|
||||||
"preserve-path": "Preserve Path",
|
"preserve-path": "Preserve Path",
|
||||||
"delete": "Delete Proxy Host",
|
"delete": "Delete Proxy Host",
|
||||||
@ -196,7 +209,10 @@
|
|||||||
"authorization": "Authorization",
|
"authorization": "Authorization",
|
||||||
"access": "Access",
|
"access": "Access",
|
||||||
"satisfy": "Satisfy",
|
"satisfy": "Satisfy",
|
||||||
"satisfy-any": "Satisfy Any"
|
"satisfy-any": "Satisfy Any",
|
||||||
|
"pass-auth": "Pass Auth to Host",
|
||||||
|
"access-add": "Add",
|
||||||
|
"auth-add": "Add"
|
||||||
},
|
},
|
||||||
"users": {
|
"users": {
|
||||||
"title": "Users",
|
"title": "Users",
|
||||||
|
@ -9,6 +9,8 @@ const model = Backbone.Model.extend({
|
|||||||
created_on: null,
|
created_on: null,
|
||||||
modified_on: null,
|
modified_on: null,
|
||||||
domain_names: [],
|
domain_names: [],
|
||||||
|
forward_http_code: 0,
|
||||||
|
forward_scheme: null,
|
||||||
forward_domain_name: '',
|
forward_domain_name: '',
|
||||||
preserve_path: true,
|
preserve_path: true,
|
||||||
certificate_id: 0,
|
certificate_id: 0,
|
||||||
|
@ -190,3 +190,7 @@
|
|||||||
.selectize-dropdown .optgroup:first-child {
|
.selectize-dropdown .optgroup:first-child {
|
||||||
border-top: 0 none;
|
border-top: 0 none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.custom-select {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
@ -25,6 +25,11 @@ $pink: #f66d9b;
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For some reason this class doesn't have 'display: flex' when it should. https://preview.tabler.io/docs/buttons.html#list-of-buttons */
|
||||||
|
.btn-list {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
/* Teal Outline Buttons */
|
/* Teal Outline Buttons */
|
||||||
.btn-outline-teal {
|
.btn-outline-teal {
|
||||||
color: $teal;
|
color: $teal;
|
||||||
|
@ -1551,10 +1551,10 @@ bluebird@^3.5.5:
|
|||||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
||||||
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
|
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
|
||||||
|
|
||||||
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0:
|
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9:
|
||||||
version "4.11.9"
|
version "4.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828"
|
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
|
||||||
integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==
|
integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
|
||||||
|
|
||||||
bn.js@^5.1.1:
|
bn.js@^5.1.1:
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
@ -1616,7 +1616,7 @@ braces@^3.0.1, braces@~3.0.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
fill-range "^7.0.1"
|
fill-range "^7.0.1"
|
||||||
|
|
||||||
brorand@^1.0.1:
|
brorand@^1.0.1, brorand@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
|
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
|
||||||
integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
|
integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
|
||||||
@ -2630,17 +2630,17 @@ electron-to-chromium@^1.3.47:
|
|||||||
integrity sha512-67V62Z4CFOiAtox+o+tosGfVk0QX4DJgH609tjT8QymbJZVAI/jWnAthnr8c5hnRNziIRwkc9EMQYejiVz3/9Q==
|
integrity sha512-67V62Z4CFOiAtox+o+tosGfVk0QX4DJgH609tjT8QymbJZVAI/jWnAthnr8c5hnRNziIRwkc9EMQYejiVz3/9Q==
|
||||||
|
|
||||||
elliptic@^6.5.3:
|
elliptic@^6.5.3:
|
||||||
version "6.5.3"
|
version "6.5.4"
|
||||||
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6"
|
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
|
||||||
integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==
|
integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
bn.js "^4.4.0"
|
bn.js "^4.11.9"
|
||||||
brorand "^1.0.1"
|
brorand "^1.1.0"
|
||||||
hash.js "^1.0.0"
|
hash.js "^1.0.0"
|
||||||
hmac-drbg "^1.0.0"
|
hmac-drbg "^1.0.1"
|
||||||
inherits "^2.0.1"
|
inherits "^2.0.4"
|
||||||
minimalistic-assert "^1.0.0"
|
minimalistic-assert "^1.0.1"
|
||||||
minimalistic-crypto-utils "^1.0.0"
|
minimalistic-crypto-utils "^1.0.1"
|
||||||
|
|
||||||
emoji-regex@^7.0.1:
|
emoji-regex@^7.0.1:
|
||||||
version "7.0.3"
|
version "7.0.3"
|
||||||
@ -3516,7 +3516,7 @@ he@1.2.x, he@^1.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||||
|
|
||||||
hmac-drbg@^1.0.0:
|
hmac-drbg@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
||||||
integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
|
integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
|
||||||
@ -3541,9 +3541,9 @@ homedir-polyfill@^1.0.1:
|
|||||||
parse-passwd "^1.0.0"
|
parse-passwd "^1.0.0"
|
||||||
|
|
||||||
hosted-git-info@^2.1.4:
|
hosted-git-info@^2.1.4:
|
||||||
version "2.8.8"
|
version "2.8.9"
|
||||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
|
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
|
||||||
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
|
integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
|
||||||
|
|
||||||
html-minifier-terser@^5.0.1:
|
html-minifier-terser@^5.0.1:
|
||||||
version "5.1.1"
|
version "5.1.1"
|
||||||
@ -3741,9 +3741,9 @@ inherits@2.0.3:
|
|||||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||||
|
|
||||||
ini@^1.3.4, ini@^1.3.5, ini@~1.3.0:
|
ini@^1.3.4, ini@^1.3.5, ini@~1.3.0:
|
||||||
version "1.3.5"
|
version "1.3.8"
|
||||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
|
||||||
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
|
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
|
||||||
|
|
||||||
inquirer@^7.0.0:
|
inquirer@^7.0.0:
|
||||||
version "7.3.3"
|
version "7.3.3"
|
||||||
@ -4278,9 +4278,9 @@ lodash.some@^4.6.0:
|
|||||||
integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=
|
integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=
|
||||||
|
|
||||||
lodash@^4.0.0, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@~4.17.10:
|
lodash@^4.0.0, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@~4.17.10:
|
||||||
version "4.17.19"
|
version "4.17.21"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
|
|
||||||
longest@^1.0.1:
|
longest@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
@ -4549,7 +4549,7 @@ minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
|
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
|
||||||
integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
|
integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
|
||||||
|
|
||||||
minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
|
minimalistic-crypto-utils@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
|
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
|
||||||
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
|
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
|
||||||
@ -6117,9 +6117,9 @@ sshpk@^1.7.0:
|
|||||||
tweetnacl "~0.14.0"
|
tweetnacl "~0.14.0"
|
||||||
|
|
||||||
ssri@^6.0.1:
|
ssri@^6.0.1:
|
||||||
version "6.0.1"
|
version "6.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8"
|
resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5"
|
||||||
integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==
|
integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
figgy-pudding "^3.5.1"
|
figgy-pudding "^3.5.1"
|
||||||
|
|
||||||
@ -6962,9 +6962,9 @@ xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.1:
|
|||||||
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||||
|
|
||||||
y18n@^4.0.0:
|
y18n@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
|
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"
|
||||||
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
|
integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==
|
||||||
|
|
||||||
yallist@^2.1.2:
|
yallist@^2.1.2:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
|
386
global/certbot-dns-plugins.js
Normal file
386
global/certbot-dns-plugins.js
Normal file
@ -0,0 +1,386 @@
|
|||||||
|
/**
|
||||||
|
* This file contains info about available Certbot DNS plugins.
|
||||||
|
* This only works for plugins which use the standard argument structure, so:
|
||||||
|
* --authenticator <plugin-name> --<plugin-name>-credentials <FILE> --<plugin-name>-propagation-seconds <number>
|
||||||
|
*
|
||||||
|
* File Structure:
|
||||||
|
*
|
||||||
|
* {
|
||||||
|
* cloudflare: {
|
||||||
|
* display_name: "Name displayed to the user",
|
||||||
|
* package_name: "Package name in PyPi repo",
|
||||||
|
* package_version: "Package version in PyPi repo",
|
||||||
|
* dependencies: "Additional dependencies, space separated (as you would pass it to pip install)",
|
||||||
|
* credentials: `Template of the credentials file`,
|
||||||
|
* full_plugin_name: "The full plugin name as used in the commandline with certbot, including prefixes, e.g. 'certbot-dns-njalla:dns-njalla'",
|
||||||
|
* },
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
//####################################################//
|
||||||
|
acmedns: {
|
||||||
|
display_name: 'ACME-DNS',
|
||||||
|
package_name: 'certbot-dns-acmedns',
|
||||||
|
package_version: '0.1.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `certbot_dns_acmedns:dns_acmedns_api_url = http://acmedns-server/
|
||||||
|
certbot_dns_acmedns:dns_acmedns_registration_file = /data/acme-registration.json`,
|
||||||
|
full_plugin_name: 'certbot-dns-acmedns:dns-acmedns',
|
||||||
|
},
|
||||||
|
aliyun: {
|
||||||
|
display_name: 'Aliyun',
|
||||||
|
package_name: 'certbot-dns-aliyun',
|
||||||
|
package_version: '0.38.1',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `certbot_dns_aliyun:dns_aliyun_access_key = 12345678
|
||||||
|
certbot_dns_aliyun:dns_aliyun_access_key_secret = 1234567890abcdef1234567890abcdef`,
|
||||||
|
full_plugin_name: 'certbot-dns-aliyun:dns-aliyun',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
azure: {
|
||||||
|
display_name: 'Azure',
|
||||||
|
package_name: 'certbot-dns-azure',
|
||||||
|
package_version: '1.1.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `# This plugin supported API authentication using either Service Principals or utilizing a Managed Identity assigned to the virtual machine.
|
||||||
|
# Regardless which authentication method used, the identity will need the “DNS Zone Contributor” role assigned to it.
|
||||||
|
# As multiple Azure DNS Zones in multiple resource groups can exist, the config file needs a mapping of zone to resource group ID. Multiple zones -> ID mappings can be listed by using the key dns_azure_zoneX where X is a unique number. At least 1 zone mapping is required.
|
||||||
|
|
||||||
|
# Using a service principal (option 1)
|
||||||
|
dns_azure_sp_client_id = 912ce44a-0156-4669-ae22-c16a17d34ca5
|
||||||
|
dns_azure_sp_client_secret = E-xqXU83Y-jzTI6xe9fs2YC~mck3ZzUih9
|
||||||
|
dns_azure_tenant_id = ed1090f3-ab18-4b12-816c-599af8a88cf7
|
||||||
|
|
||||||
|
# Using used assigned MSI (option 2)
|
||||||
|
# dns_azure_msi_client_id = 912ce44a-0156-4669-ae22-c16a17d34ca5
|
||||||
|
|
||||||
|
# Using system assigned MSI (option 3)
|
||||||
|
# dns_azure_msi_system_assigned = true
|
||||||
|
|
||||||
|
# Zones (at least one always required)
|
||||||
|
dns_azure_zone1 = example.com:/subscriptions/c135abce-d87d-48df-936c-15596c6968a5/resourceGroups/dns1
|
||||||
|
dns_azure_zone2 = example.org:/subscriptions/99800903-fb14-4992-9aff-12eaf2744622/resourceGroups/dns2`,
|
||||||
|
full_plugin_name: 'dns-azure',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
cloudflare: {
|
||||||
|
display_name: 'Cloudflare',
|
||||||
|
package_name: 'certbot-dns-cloudflare',
|
||||||
|
package_version: '1.8.0',
|
||||||
|
dependencies: 'cloudflare',
|
||||||
|
credentials: `# Cloudflare API token
|
||||||
|
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567`,
|
||||||
|
full_plugin_name: 'dns-cloudflare',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
cloudns: {
|
||||||
|
display_name: 'ClouDNS',
|
||||||
|
package_name: 'certbot-dns-cloudns',
|
||||||
|
package_version: '0.4.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `# Target user ID (see https://www.cloudns.net/api-settings/)
|
||||||
|
dns_cloudns_auth_id=1234
|
||||||
|
# Alternatively, one of the following two options can be set:
|
||||||
|
# dns_cloudns_sub_auth_id=1234
|
||||||
|
# dns_cloudns_sub_auth_user=foobar
|
||||||
|
|
||||||
|
# API password
|
||||||
|
dns_cloudns_auth_password=password1`,
|
||||||
|
full_plugin_name: 'dns-cloudns',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
cloudxns: {
|
||||||
|
display_name: 'CloudXNS',
|
||||||
|
package_name: 'certbot-dns-cloudxns',
|
||||||
|
package_version: '1.8.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `dns_cloudxns_api_key = 1234567890abcdef1234567890abcdef
|
||||||
|
dns_cloudxns_secret_key = 1122334455667788`,
|
||||||
|
full_plugin_name: 'dns-cloudxns',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
corenetworks: {
|
||||||
|
display_name: 'Core Networks',
|
||||||
|
package_name: 'certbot-dns-corenetworks',
|
||||||
|
package_version: '0.1.4',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `certbot_dns_corenetworks:dns_corenetworks_username = asaHB12r
|
||||||
|
certbot_dns_corenetworks:dns_corenetworks_password = secure_password`,
|
||||||
|
full_plugin_name: 'certbot-dns-corenetworks:dns-corenetworks',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
cpanel: {
|
||||||
|
display_name: 'cPanel',
|
||||||
|
package_name: 'certbot-dns-cpanel',
|
||||||
|
package_version: '0.2.2',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `certbot_dns_cpanel:cpanel_url = https://cpanel.example.com:2083
|
||||||
|
certbot_dns_cpanel:cpanel_username = user
|
||||||
|
certbot_dns_cpanel:cpanel_password = hunter2`,
|
||||||
|
full_plugin_name: 'certbot-dns-cpanel:cpanel',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
duckdns: {
|
||||||
|
display_name: 'DuckDNS',
|
||||||
|
package_name: 'certbot-dns-duckdns',
|
||||||
|
package_version: '0.5',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: 'dns_duckdns_token=<your-duckdns-token>',
|
||||||
|
full_plugin_name: 'dns-duckdns',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
digitalocean: {
|
||||||
|
display_name: 'DigitalOcean',
|
||||||
|
package_name: 'certbot-dns-digitalocean',
|
||||||
|
package_version: '1.8.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: 'dns_digitalocean_token = 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff',
|
||||||
|
full_plugin_name: 'dns-digitalocean',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
directadmin: {
|
||||||
|
display_name: 'DirectAdmin',
|
||||||
|
package_name: 'certbot-dns-directadmin',
|
||||||
|
package_version: '0.0.20',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `directadmin_url = https://my.directadminserver.com:2222
|
||||||
|
directadmin_username = username
|
||||||
|
directadmin_password = aSuperStrongPassword`,
|
||||||
|
full_plugin_name: 'certbot-dns-directadmin:directadmin',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
dnsimple: {
|
||||||
|
display_name: 'DNSimple',
|
||||||
|
package_name: 'certbot-dns-dnsimple',
|
||||||
|
package_version: '1.8.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: 'dns_dnsimple_token = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw',
|
||||||
|
full_plugin_name: 'dns-dnsimple',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
dnsmadeeasy: {
|
||||||
|
display_name: 'DNS Made Easy',
|
||||||
|
package_name: 'certbot-dns-dnsmadeeasy',
|
||||||
|
package_version: '1.8.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `dns_dnsmadeeasy_api_key = 1c1a3c91-4770-4ce7-96f4-54c0eb0e457a
|
||||||
|
dns_dnsmadeeasy_secret_key = c9b5625f-9834-4ff8-baba-4ed5f32cae55`,
|
||||||
|
full_plugin_name: 'dns-dnsmadeeasy',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
dnspod: {
|
||||||
|
display_name: 'DNSPod',
|
||||||
|
package_name: 'certbot-dns-dnspod',
|
||||||
|
package_version: '0.1.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `certbot_dns_dnspod:dns_dnspod_email = "DNSPOD-API-REQUIRES-A-VALID-EMAIL"
|
||||||
|
certbot_dns_dnspod:dns_dnspod_api_token = "DNSPOD-API-TOKEN"`,
|
||||||
|
full_plugin_name: 'certbot-dns-dnspod:dns-dnspod',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
eurodns: {
|
||||||
|
display_name: 'EuroDNS',
|
||||||
|
package_name: 'certbot-dns-eurodns',
|
||||||
|
package_version: '0.0.4',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `dns_eurodns_applicationId = myuser
|
||||||
|
dns_eurodns_apiKey = mysecretpassword
|
||||||
|
dns_eurodns_endpoint = https://rest-api.eurodns.com/user-api-gateway/proxy`,
|
||||||
|
full_plugin_name: 'certbot-dns-eurodns:dns-eurodns',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
gandi: {
|
||||||
|
display_name: 'Gandi Live DNS',
|
||||||
|
package_name: 'certbot_plugin_gandi',
|
||||||
|
package_version: '1.2.5',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: 'certbot_plugin_gandi:dns_api_key = APIKEY',
|
||||||
|
full_plugin_name: 'certbot-plugin-gandi:dns',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
google: {
|
||||||
|
display_name: 'Google',
|
||||||
|
package_name: 'certbot-dns-google',
|
||||||
|
package_version: '1.8.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `{
|
||||||
|
"type": "service_account",
|
||||||
|
...
|
||||||
|
}`,
|
||||||
|
full_plugin_name: 'dns-google',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
hetzner: {
|
||||||
|
display_name: 'Hetzner',
|
||||||
|
package_name: 'certbot-dns-hetzner',
|
||||||
|
package_version: '1.0.4',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: 'certbot_dns_hetzner:dns_hetzner_api_token = 0123456789abcdef0123456789abcdef',
|
||||||
|
full_plugin_name: 'certbot-dns-hetzner:dns-hetzner',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
inwx: {
|
||||||
|
display_name: 'INWX',
|
||||||
|
package_name: 'certbot-dns-inwx',
|
||||||
|
package_version: '2.1.2',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `certbot_dns_inwx:dns_inwx_url = https://api.domrobot.com/xmlrpc/
|
||||||
|
certbot_dns_inwx:dns_inwx_username = your_username
|
||||||
|
certbot_dns_inwx:dns_inwx_password = your_password
|
||||||
|
certbot_dns_inwx:dns_inwx_shared_secret = your_shared_secret optional`,
|
||||||
|
full_plugin_name: 'certbot-dns-inwx:dns-inwx',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
ispconfig: {
|
||||||
|
display_name: 'ISPConfig',
|
||||||
|
package_name: 'certbot-dns-ispconfig',
|
||||||
|
package_version: '0.2.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `certbot_dns_ispconfig:dns_ispconfig_username = myremoteuser
|
||||||
|
certbot_dns_ispconfig:dns_ispconfig_password = verysecureremoteuserpassword
|
||||||
|
certbot_dns_ispconfig:dns_ispconfig_endpoint = https://localhost:8080`,
|
||||||
|
full_plugin_name: 'certbot-dns-ispconfig:dns-ispconfig',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
isset: {
|
||||||
|
display_name: 'Isset',
|
||||||
|
package_name: 'certbot-dns-isset',
|
||||||
|
package_version: '0.0.3',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `certbot_dns_isset:dns_isset_endpoint="https://customer.isset.net/api"
|
||||||
|
certbot_dns_isset:dns_isset_token="<token>"`,
|
||||||
|
full_plugin_name: 'certbot-dns-isset:dns-isset',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
linode: {
|
||||||
|
display_name: 'Linode',
|
||||||
|
package_name: 'certbot-dns-linode',
|
||||||
|
package_version: '1.8.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `dns_linode_key = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ64
|
||||||
|
dns_linode_version = [<blank>|3|4]`,
|
||||||
|
full_plugin_name: 'dns-linode',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
luadns: {
|
||||||
|
display_name: 'LuaDNS',
|
||||||
|
package_name: 'certbot-dns-luadns',
|
||||||
|
package_version: '1.8.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `dns_luadns_email = user@example.com
|
||||||
|
dns_luadns_token = 0123456789abcdef0123456789abcdef`,
|
||||||
|
full_plugin_name: 'dns-luadns',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
netcup: {
|
||||||
|
display_name: 'netcup',
|
||||||
|
package_name: 'certbot-dns-netcup',
|
||||||
|
package_version: '1.0.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `certbot_dns_netcup:dns_netcup_customer_id = 123456
|
||||||
|
certbot_dns_netcup:dns_netcup_api_key = 0123456789abcdef0123456789abcdef01234567
|
||||||
|
certbot_dns_netcup:dns_netcup_api_password = abcdef0123456789abcdef01234567abcdef0123`,
|
||||||
|
full_plugin_name: 'certbot-dns-netcup:dns-netcup',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
njalla: {
|
||||||
|
display_name: 'Njalla',
|
||||||
|
package_name: 'certbot-dns-njalla',
|
||||||
|
package_version: '1.0.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: 'certbot_dns_njalla:dns_njalla_token = 0123456789abcdef0123456789abcdef01234567',
|
||||||
|
full_plugin_name: 'certbot-dns-njalla:dns-njalla',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
nsone: {
|
||||||
|
display_name: 'NS1',
|
||||||
|
package_name: 'certbot-dns-nsone',
|
||||||
|
package_version: '1.8.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: 'dns_nsone_api_key = MDAwMDAwMDAwMDAwMDAw',
|
||||||
|
full_plugin_name: 'dns-nsone',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
ovh: {
|
||||||
|
display_name: 'OVH',
|
||||||
|
package_name: 'certbot-dns-ovh',
|
||||||
|
package_version: '1.8.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `dns_ovh_endpoint = ovh-eu
|
||||||
|
dns_ovh_application_key = MDAwMDAwMDAwMDAw
|
||||||
|
dns_ovh_application_secret = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
|
||||||
|
dns_ovh_consumer_key = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw`,
|
||||||
|
full_plugin_name: 'dns-ovh',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
powerdns: {
|
||||||
|
display_name: 'PowerDNS',
|
||||||
|
package_name: 'certbot-dns-powerdns',
|
||||||
|
package_version: '0.2.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `certbot_dns_powerdns:dns_powerdns_api_url = https://api.mypowerdns.example.org
|
||||||
|
certbot_dns_powerdns:dns_powerdns_api_key = AbCbASsd!@34`,
|
||||||
|
full_plugin_name: 'certbot-dns-powerdns:dns-powerdns',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
regru: {
|
||||||
|
display_name: 'reg.ru',
|
||||||
|
package_name: 'certbot-regru',
|
||||||
|
package_version: '1.0.2',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `certbot_regru:dns_username=username
|
||||||
|
certbot_regru:dns_password=password`,
|
||||||
|
full_plugin_name: 'certbot-regru:dns',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
rfc2136: {
|
||||||
|
display_name: 'RFC 2136',
|
||||||
|
package_name: 'certbot-dns-rfc2136',
|
||||||
|
package_version: '1.8.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `# Target DNS server
|
||||||
|
dns_rfc2136_server = 192.0.2.1
|
||||||
|
# Target DNS port
|
||||||
|
dns_rfc2136_port = 53
|
||||||
|
# TSIG key name
|
||||||
|
dns_rfc2136_name = keyname.
|
||||||
|
# TSIG key secret
|
||||||
|
dns_rfc2136_secret = 4q4wM/2I180UXoMyN4INVhJNi8V9BCV+jMw2mXgZw/CSuxUT8C7NKKFs AmKd7ak51vWKgSl12ib86oQRPkpDjg==
|
||||||
|
# TSIG key algorithm
|
||||||
|
dns_rfc2136_algorithm = HMAC-SHA512`,
|
||||||
|
full_plugin_name: 'dns-rfc2136',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
route53: {
|
||||||
|
display_name: 'Route 53 (Amazon)',
|
||||||
|
package_name: 'certbot-dns-route53',
|
||||||
|
package_version: '1.8.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `[default]
|
||||||
|
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
|
||||||
|
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY`,
|
||||||
|
full_plugin_name: 'dns-route53',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
transip: {
|
||||||
|
display_name: 'TransIP',
|
||||||
|
package_name: 'certbot-dns-transip',
|
||||||
|
package_version: '0.3.3',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `certbot_dns_transip:dns_transip_username = my_username
|
||||||
|
certbot_dns_transip:dns_transip_key_file = /etc/letsencrypt/transip-rsa.key`,
|
||||||
|
full_plugin_name: 'certbot-dns-transip:dns-transip',
|
||||||
|
},
|
||||||
|
//####################################################//
|
||||||
|
vultr: {
|
||||||
|
display_name: 'Vultr',
|
||||||
|
package_name: 'certbot-dns-vultr',
|
||||||
|
package_version: '1.0.3',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: 'certbot_dns_vultr:dns_vultr_key = YOUR_VULTR_API_KEY',
|
||||||
|
full_plugin_name: 'certbot-dns-vultr:dns-vultr',
|
||||||
|
},
|
||||||
|
};
|
@ -3,14 +3,14 @@
|
|||||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
. "$DIR/.common.sh"
|
. "$DIR/.common.sh"
|
||||||
|
|
||||||
DOCKER_IMAGE=jc21/alpine-nginx-full:node
|
DOCKER_IMAGE=jc21/nginx-full:node
|
||||||
|
|
||||||
# Ensure docker exists
|
# Ensure docker exists
|
||||||
if hash docker 2>/dev/null; then
|
if hash docker 2>/dev/null; then
|
||||||
docker pull "${DOCKER_IMAGE}"
|
docker pull "${DOCKER_IMAGE}"
|
||||||
cd "${DIR}/.."
|
cd "${DIR}/.."
|
||||||
echo -e "${BLUE}❯ ${CYAN}Building Frontend ...${RESET}"
|
echo -e "${BLUE}❯ ${CYAN}Building Frontend ...${RESET}"
|
||||||
docker run --rm -e CI=true -v "$(pwd)/frontend:/app/frontend" -w /app/frontend "$DOCKER_IMAGE" sh -c "yarn install && yarn build && yarn build && chown -R $(id -u):$(id -g) /app/frontend"
|
docker run --rm -e CI=true -v "$(pwd)/frontend:/app/frontend" -v "$(pwd)/global:/app/global" -w /app/frontend "$DOCKER_IMAGE" sh -c "yarn install && yarn build && yarn build && chown -R $(id -u):$(id -g) /app/frontend"
|
||||||
echo -e "${BLUE}❯ ${GREEN}Building Frontend Complete${RESET}"
|
echo -e "${BLUE}❯ ${GREEN}Building Frontend Complete${RESET}"
|
||||||
else
|
else
|
||||||
echo -e "${RED}❯ docker command is not available${RESET}"
|
echo -e "${RED}❯ docker command is not available${RESET}"
|
||||||
|
@ -7,7 +7,7 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||||||
if hash docker-compose 2>/dev/null; then
|
if hash docker-compose 2>/dev/null; then
|
||||||
cd "${DIR}/.."
|
cd "${DIR}/.."
|
||||||
echo -e "${BLUE}❯ ${CYAN}Testing Dev Stack ...${RESET}"
|
echo -e "${BLUE}❯ ${CYAN}Testing Dev Stack ...${RESET}"
|
||||||
docker-compose exec -T npm bash -c "cd /app/backend && task test"
|
docker-compose exec -T npm bash -c "cd /app && task test"
|
||||||
else
|
else
|
||||||
echo -e "${RED}❯ docker-compose command is not available${RESET}"
|
echo -e "${RED}❯ docker-compose command is not available${RESET}"
|
||||||
fi
|
fi
|
||||||
|
1
test/.dockerignore
Normal file
1
test/.dockerignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
node_modules
|
@ -1,6 +1,11 @@
|
|||||||
FROM cypress/included:4.12.1
|
FROM cypress/included:5.6.0
|
||||||
|
|
||||||
COPY --chown=1000 ./test /test
|
COPY --chown=1000 ./ /test
|
||||||
|
|
||||||
|
# mkcert
|
||||||
|
ENV MKCERT=1.4.2
|
||||||
|
RUN wget -O /usr/bin/mkcert "https://github.com/FiloSottile/mkcert/releases/download/v${MKCERT}/mkcert-v${MKCERT}-linux-amd64" \
|
||||||
|
&& chmod +x /usr/bin/mkcert
|
||||||
|
|
||||||
WORKDIR /test
|
WORKDIR /test
|
||||||
RUN yarn install
|
RUN yarn install
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"@jc21/cypress-swagger-validation": "^0.0.9",
|
"@jc21/cypress-swagger-validation": "^0.0.9",
|
||||||
"@jc21/restler": "^3.4.0",
|
"@jc21/restler": "^3.4.0",
|
||||||
"chalk": "^4.1.0",
|
"chalk": "^4.1.0",
|
||||||
"cypress": "^4.12.1",
|
"cypress": "^5.6.0",
|
||||||
"cypress-multi-reporters": "^1.4.0",
|
"cypress-multi-reporters": "^1.4.0",
|
||||||
"cypress-plugin-retries": "^1.5.2",
|
"cypress-plugin-retries": "^1.5.2",
|
||||||
"eslint": "^7.6.0",
|
"eslint": "^7.6.0",
|
||||||
|
311
test/yarn.lock
311
test/yarn.lock
@ -262,6 +262,11 @@ asynckit@^0.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||||
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
||||||
|
|
||||||
|
at-least-node@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
|
||||||
|
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
|
||||||
|
|
||||||
aws-sign2@~0.7.0:
|
aws-sign2@~0.7.0:
|
||||||
version "0.7.0"
|
version "0.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
||||||
@ -289,6 +294,11 @@ binary-extensions@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9"
|
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9"
|
||||||
integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==
|
integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==
|
||||||
|
|
||||||
|
blob-util@2.0.2:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/blob-util/-/blob-util-2.0.2.tgz#3b4e3c281111bb7f11128518006cdc60b403a1eb"
|
||||||
|
integrity sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==
|
||||||
|
|
||||||
bluebird@^3.7.2:
|
bluebird@^3.7.2:
|
||||||
version "3.7.2"
|
version "3.7.2"
|
||||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
||||||
@ -429,13 +439,13 @@ cli-cursor@^2.0.0, cli-cursor@^2.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
restore-cursor "^2.0.0"
|
restore-cursor "^2.0.0"
|
||||||
|
|
||||||
cli-table3@~0.5.1:
|
cli-table3@~0.6.0:
|
||||||
version "0.5.1"
|
version "0.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202"
|
resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.0.tgz#b7b1bc65ca8e7b5cef9124e13dc2b21e2ce4faee"
|
||||||
integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==
|
integrity sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
object-assign "^4.1.0"
|
object-assign "^4.1.0"
|
||||||
string-width "^2.1.1"
|
string-width "^4.2.0"
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
colors "^1.1.2"
|
colors "^1.1.2"
|
||||||
|
|
||||||
@ -497,10 +507,10 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
|
|||||||
dependencies:
|
dependencies:
|
||||||
delayed-stream "~1.0.0"
|
delayed-stream "~1.0.0"
|
||||||
|
|
||||||
commander@^4.1.1:
|
commander@^5.1.0:
|
||||||
version "4.1.1"
|
version "5.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
|
||||||
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
|
integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==
|
||||||
|
|
||||||
common-tags@^1.8.0:
|
common-tags@^1.8.0:
|
||||||
version "1.8.0"
|
version "1.8.0"
|
||||||
@ -527,18 +537,7 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||||
|
|
||||||
cross-spawn@^6.0.0:
|
cross-spawn@^7.0.0, cross-spawn@^7.0.2:
|
||||||
version "6.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
|
||||||
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
|
|
||||||
dependencies:
|
|
||||||
nice-try "^1.0.4"
|
|
||||||
path-key "^2.0.1"
|
|
||||||
semver "^5.5.0"
|
|
||||||
shebang-command "^1.2.0"
|
|
||||||
which "^1.2.9"
|
|
||||||
|
|
||||||
cross-spawn@^7.0.2:
|
|
||||||
version "7.0.3"
|
version "7.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||||
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||||
@ -567,10 +566,10 @@ cypress-plugin-retries@^1.5.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
chalk "^3.0.0"
|
chalk "^3.0.0"
|
||||||
|
|
||||||
cypress@^4.12.1:
|
cypress@^5.6.0:
|
||||||
version "4.12.1"
|
version "5.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/cypress/-/cypress-4.12.1.tgz#0ead1b9f4c0917d69d8b57f996b6e01fe693b6ec"
|
resolved "https://registry.yarnpkg.com/cypress/-/cypress-5.6.0.tgz#6781755c3ddfd644ce3179fcd7389176c0c82280"
|
||||||
integrity sha512-9SGIPEmqU8vuRA6xst2CMTYd9sCFCxKSzrHt0wr+w2iAQMCIIsXsQ5Gplns1sT6LDbZcmLv6uehabAOl3fhc9Q==
|
integrity sha512-cs5vG3E2JLldAc16+5yQxaVRLLqMVya5RlrfPWkC72S5xrlHFdw7ovxPb61s4wYweROKTyH01WQc2PFzwwVvyQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@cypress/listr-verbose-renderer" "^0.4.1"
|
"@cypress/listr-verbose-renderer" "^0.4.1"
|
||||||
"@cypress/request" "^2.88.5"
|
"@cypress/request" "^2.88.5"
|
||||||
@ -578,34 +577,35 @@ cypress@^4.12.1:
|
|||||||
"@types/sinonjs__fake-timers" "^6.0.1"
|
"@types/sinonjs__fake-timers" "^6.0.1"
|
||||||
"@types/sizzle" "^2.3.2"
|
"@types/sizzle" "^2.3.2"
|
||||||
arch "^2.1.2"
|
arch "^2.1.2"
|
||||||
|
blob-util "2.0.2"
|
||||||
bluebird "^3.7.2"
|
bluebird "^3.7.2"
|
||||||
cachedir "^2.3.0"
|
cachedir "^2.3.0"
|
||||||
chalk "^2.4.2"
|
chalk "^4.1.0"
|
||||||
check-more-types "^2.24.0"
|
check-more-types "^2.24.0"
|
||||||
cli-table3 "~0.5.1"
|
cli-table3 "~0.6.0"
|
||||||
commander "^4.1.1"
|
commander "^5.1.0"
|
||||||
common-tags "^1.8.0"
|
common-tags "^1.8.0"
|
||||||
debug "^4.1.1"
|
debug "^4.1.1"
|
||||||
eventemitter2 "^6.4.2"
|
eventemitter2 "^6.4.2"
|
||||||
execa "^1.0.0"
|
execa "^4.0.2"
|
||||||
executable "^4.1.1"
|
executable "^4.1.1"
|
||||||
extract-zip "^1.7.0"
|
extract-zip "^1.7.0"
|
||||||
fs-extra "^8.1.0"
|
fs-extra "^9.0.1"
|
||||||
getos "^3.2.1"
|
getos "^3.2.1"
|
||||||
is-ci "^2.0.0"
|
is-ci "^2.0.0"
|
||||||
is-installed-globally "^0.3.2"
|
is-installed-globally "^0.3.2"
|
||||||
lazy-ass "^1.6.0"
|
lazy-ass "^1.6.0"
|
||||||
listr "^0.14.3"
|
listr "^0.14.3"
|
||||||
lodash "^4.17.19"
|
lodash "^4.17.19"
|
||||||
log-symbols "^3.0.0"
|
log-symbols "^4.0.0"
|
||||||
minimist "^1.2.5"
|
minimist "^1.2.5"
|
||||||
moment "^2.27.0"
|
moment "^2.27.0"
|
||||||
ospath "^1.2.2"
|
ospath "^1.2.2"
|
||||||
pretty-bytes "^5.3.0"
|
pretty-bytes "^5.4.1"
|
||||||
ramda "~0.26.1"
|
ramda "~0.26.1"
|
||||||
request-progress "^3.0.0"
|
request-progress "^3.0.0"
|
||||||
supports-color "^7.1.0"
|
supports-color "^7.2.0"
|
||||||
tmp "~0.1.0"
|
tmp "~0.2.1"
|
||||||
untildify "^4.0.0"
|
untildify "^4.0.0"
|
||||||
url "^0.11.0"
|
url "^0.11.0"
|
||||||
yauzl "^2.10.0"
|
yauzl "^2.10.0"
|
||||||
@ -695,6 +695,11 @@ emoji-regex@^7.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
|
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
|
||||||
integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
|
integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
|
||||||
|
|
||||||
|
emoji-regex@^8.0.0:
|
||||||
|
version "8.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
|
||||||
|
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
|
||||||
|
|
||||||
end-of-stream@^1.1.0:
|
end-of-stream@^1.1.0:
|
||||||
version "1.4.4"
|
version "1.4.4"
|
||||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
||||||
@ -929,18 +934,20 @@ eventemitter2@^6.4.2:
|
|||||||
resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.3.tgz#35c563619b13f3681e7eb05cbdaf50f56ba58820"
|
resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.3.tgz#35c563619b13f3681e7eb05cbdaf50f56ba58820"
|
||||||
integrity sha512-t0A2msp6BzOf+QAcI6z9XMktLj52OjGQg+8SJH6v5+3uxNpWYRR3wQmfA+6xtMU9kOC59qk9licus5dYcrYkMQ==
|
integrity sha512-t0A2msp6BzOf+QAcI6z9XMktLj52OjGQg+8SJH6v5+3uxNpWYRR3wQmfA+6xtMU9kOC59qk9licus5dYcrYkMQ==
|
||||||
|
|
||||||
execa@^1.0.0:
|
execa@^4.0.2:
|
||||||
version "1.0.0"
|
version "4.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
|
resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a"
|
||||||
integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
|
integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==
|
||||||
dependencies:
|
dependencies:
|
||||||
cross-spawn "^6.0.0"
|
cross-spawn "^7.0.0"
|
||||||
get-stream "^4.0.0"
|
get-stream "^5.0.0"
|
||||||
is-stream "^1.1.0"
|
human-signals "^1.1.1"
|
||||||
npm-run-path "^2.0.0"
|
is-stream "^2.0.0"
|
||||||
p-finally "^1.0.0"
|
merge-stream "^2.0.0"
|
||||||
signal-exit "^3.0.0"
|
npm-run-path "^4.0.0"
|
||||||
strip-eof "^1.0.0"
|
onetime "^5.1.0"
|
||||||
|
signal-exit "^3.0.2"
|
||||||
|
strip-final-newline "^2.0.0"
|
||||||
|
|
||||||
executable@^4.1.1:
|
executable@^4.1.1:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
@ -1085,14 +1092,15 @@ form-data@~2.3.2:
|
|||||||
combined-stream "^1.0.6"
|
combined-stream "^1.0.6"
|
||||||
mime-types "^2.1.12"
|
mime-types "^2.1.12"
|
||||||
|
|
||||||
fs-extra@^8.1.0:
|
fs-extra@^9.0.1:
|
||||||
version "8.1.0"
|
version "9.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
|
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
|
||||||
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
|
integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
|
at-least-node "^1.0.0"
|
||||||
graceful-fs "^4.2.0"
|
graceful-fs "^4.2.0"
|
||||||
jsonfile "^4.0.0"
|
jsonfile "^6.0.1"
|
||||||
universalify "^0.1.0"
|
universalify "^2.0.0"
|
||||||
|
|
||||||
fs.realpath@^1.0.0:
|
fs.realpath@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
@ -1119,10 +1127,10 @@ get-caller-file@^2.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||||
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||||
|
|
||||||
get-stream@^4.0.0:
|
get-stream@^5.0.0:
|
||||||
version "4.1.0"
|
version "5.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
|
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
|
||||||
integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
|
integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
|
||||||
dependencies:
|
dependencies:
|
||||||
pump "^3.0.0"
|
pump "^3.0.0"
|
||||||
|
|
||||||
@ -1251,6 +1259,11 @@ http-signature@~1.2.0:
|
|||||||
jsprim "^1.2.2"
|
jsprim "^1.2.2"
|
||||||
sshpk "^1.7.0"
|
sshpk "^1.7.0"
|
||||||
|
|
||||||
|
human-signals@^1.1.1:
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
|
||||||
|
integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
|
||||||
|
|
||||||
iconv-lite@0.2.11:
|
iconv-lite@0.2.11:
|
||||||
version "0.2.11"
|
version "0.2.11"
|
||||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.2.11.tgz#1ce60a3a57864a292d1321ff4609ca4bb965adc8"
|
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.2.11.tgz#1ce60a3a57864a292d1321ff4609ca4bb965adc8"
|
||||||
@ -1293,9 +1306,9 @@ inherits@2, inherits@^2.0.3, inherits@~2.0.3:
|
|||||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||||
|
|
||||||
ini@^1.3.5:
|
ini@^1.3.5:
|
||||||
version "1.3.5"
|
version "1.3.8"
|
||||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
|
||||||
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
|
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
|
||||||
|
|
||||||
is-arguments@^1.0.4:
|
is-arguments@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
@ -1358,6 +1371,11 @@ is-fullwidth-code-point@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
|
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
|
||||||
integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
|
integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
|
||||||
|
|
||||||
|
is-fullwidth-code-point@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
|
||||||
|
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
|
||||||
|
|
||||||
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
|
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
|
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
|
||||||
@ -1429,6 +1447,11 @@ is-stream@^1.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||||
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
||||||
|
|
||||||
|
is-stream@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3"
|
||||||
|
integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==
|
||||||
|
|
||||||
is-string@^1.0.4, is-string@^1.0.5:
|
is-string@^1.0.4, is-string@^1.0.5:
|
||||||
version "1.0.5"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6"
|
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6"
|
||||||
@ -1446,6 +1469,11 @@ is-typedarray@~1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
||||||
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
|
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
|
||||||
|
|
||||||
|
is-unicode-supported@^0.1.0:
|
||||||
|
version "0.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
|
||||||
|
integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
|
||||||
|
|
||||||
isarray@^2.0.5:
|
isarray@^2.0.5:
|
||||||
version "2.0.5"
|
version "2.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
|
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
|
||||||
@ -1529,10 +1557,12 @@ json-stringify-safe@~5.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
||||||
|
|
||||||
jsonfile@^4.0.0:
|
jsonfile@^6.0.1:
|
||||||
version "4.0.0"
|
version "6.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
|
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
|
||||||
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
|
integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
|
||||||
|
dependencies:
|
||||||
|
universalify "^2.0.0"
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
graceful-fs "^4.1.6"
|
graceful-fs "^4.1.6"
|
||||||
|
|
||||||
@ -1640,17 +1670,12 @@ lodash.once@^4.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
||||||
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
|
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
|
||||||
|
|
||||||
lodash@^4.17.14, lodash@^4.17.15:
|
lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19:
|
||||||
version "4.17.15"
|
version "4.17.21"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
|
|
||||||
lodash@^4.17.19:
|
log-symbols@3.0.0:
|
||||||
version "4.17.19"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
|
|
||||||
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
|
|
||||||
|
|
||||||
log-symbols@3.0.0, log-symbols@^3.0.0:
|
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4"
|
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4"
|
||||||
integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==
|
integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==
|
||||||
@ -1664,6 +1689,14 @@ log-symbols@^1.0.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
chalk "^1.0.0"
|
chalk "^1.0.0"
|
||||||
|
|
||||||
|
log-symbols@^4.0.0:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
|
||||||
|
integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
|
||||||
|
dependencies:
|
||||||
|
chalk "^4.1.0"
|
||||||
|
is-unicode-supported "^0.1.0"
|
||||||
|
|
||||||
log-update@^2.3.0:
|
log-update@^2.3.0:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708"
|
resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708"
|
||||||
@ -1682,6 +1715,11 @@ md5@^2.1.0:
|
|||||||
crypt "~0.0.1"
|
crypt "~0.0.1"
|
||||||
is-buffer "~1.1.1"
|
is-buffer "~1.1.1"
|
||||||
|
|
||||||
|
merge-stream@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
|
||||||
|
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
|
||||||
|
|
||||||
mime-db@1.42.0:
|
mime-db@1.42.0:
|
||||||
version "1.42.0"
|
version "1.42.0"
|
||||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac"
|
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac"
|
||||||
@ -1699,6 +1737,11 @@ mimic-fn@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
|
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
|
||||||
integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
|
integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
|
||||||
|
|
||||||
|
mimic-fn@^2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||||
|
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
|
||||||
|
|
||||||
minimatch@3.0.4, minimatch@^3.0.4:
|
minimatch@3.0.4, minimatch@^3.0.4:
|
||||||
version "3.0.4"
|
version "3.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||||
@ -1792,22 +1835,17 @@ natural-compare@^1.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||||
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
||||||
|
|
||||||
nice-try@^1.0.4:
|
|
||||||
version "1.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
|
||||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
|
||||||
|
|
||||||
normalize-path@^3.0.0, normalize-path@~3.0.0:
|
normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||||
|
|
||||||
npm-run-path@^2.0.0:
|
npm-run-path@^4.0.0:
|
||||||
version "2.0.2"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
|
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
|
||||||
integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
|
integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
|
||||||
dependencies:
|
dependencies:
|
||||||
path-key "^2.0.0"
|
path-key "^3.0.0"
|
||||||
|
|
||||||
number-is-nan@^1.0.0:
|
number-is-nan@^1.0.0:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
@ -1863,6 +1901,13 @@ onetime@^2.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
mimic-fn "^1.0.0"
|
mimic-fn "^1.0.0"
|
||||||
|
|
||||||
|
onetime@^5.1.0:
|
||||||
|
version "5.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
|
||||||
|
integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
|
||||||
|
dependencies:
|
||||||
|
mimic-fn "^2.1.0"
|
||||||
|
|
||||||
optionator@^0.8.1:
|
optionator@^0.8.1:
|
||||||
version "0.8.3"
|
version "0.8.3"
|
||||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
|
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
|
||||||
@ -1892,11 +1937,6 @@ ospath@^1.2.2:
|
|||||||
resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b"
|
resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b"
|
||||||
integrity sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=
|
integrity sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=
|
||||||
|
|
||||||
p-finally@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
|
|
||||||
integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
|
|
||||||
|
|
||||||
p-limit@^2.0.0:
|
p-limit@^2.0.0:
|
||||||
version "2.2.2"
|
version "2.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e"
|
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e"
|
||||||
@ -1957,12 +1997,7 @@ path-is-absolute@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||||
|
|
||||||
path-key@^2.0.0, path-key@^2.0.1:
|
path-key@^3.0.0, path-key@^3.1.0:
|
||||||
version "2.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
|
|
||||||
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
|
|
||||||
|
|
||||||
path-key@^3.1.0:
|
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
||||||
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
||||||
@ -1997,10 +2032,10 @@ prelude-ls@~1.1.2:
|
|||||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
||||||
integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
|
integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
|
||||||
|
|
||||||
pretty-bytes@^5.3.0:
|
pretty-bytes@^5.4.1:
|
||||||
version "5.3.0"
|
version "5.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2"
|
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
|
||||||
integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==
|
integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==
|
||||||
|
|
||||||
process-nextick-args@~2.0.0:
|
process-nextick-args@~2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
@ -2143,10 +2178,10 @@ rimraf@2.6.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
glob "^7.1.3"
|
glob "^7.1.3"
|
||||||
|
|
||||||
rimraf@^2.6.3:
|
rimraf@^3.0.0:
|
||||||
version "2.7.1"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
|
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
|
||||||
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
|
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
|
||||||
dependencies:
|
dependencies:
|
||||||
glob "^7.1.3"
|
glob "^7.1.3"
|
||||||
|
|
||||||
@ -2182,11 +2217,6 @@ sax@0.5.x:
|
|||||||
resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1"
|
resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1"
|
||||||
integrity sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=
|
integrity sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=
|
||||||
|
|
||||||
semver@^5.5.0:
|
|
||||||
version "5.7.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
|
||||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
|
||||||
|
|
||||||
semver@^7.2.1:
|
semver@^7.2.1:
|
||||||
version "7.3.2"
|
version "7.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
|
||||||
@ -2204,13 +2234,6 @@ set-blocking@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
||||||
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
|
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
|
||||||
|
|
||||||
shebang-command@^1.2.0:
|
|
||||||
version "1.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
|
||||||
integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
|
|
||||||
dependencies:
|
|
||||||
shebang-regex "^1.0.0"
|
|
||||||
|
|
||||||
shebang-command@^2.0.0:
|
shebang-command@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
|
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
|
||||||
@ -2218,17 +2241,12 @@ shebang-command@^2.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
shebang-regex "^3.0.0"
|
shebang-regex "^3.0.0"
|
||||||
|
|
||||||
shebang-regex@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
|
|
||||||
integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
|
|
||||||
|
|
||||||
shebang-regex@^3.0.0:
|
shebang-regex@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
|
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
|
||||||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||||
|
|
||||||
signal-exit@^3.0.0, signal-exit@^3.0.2:
|
signal-exit@^3.0.2:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
||||||
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
|
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
|
||||||
@ -2305,6 +2323,15 @@ string-width@^3.0.0, string-width@^3.1.0:
|
|||||||
is-fullwidth-code-point "^2.0.0"
|
is-fullwidth-code-point "^2.0.0"
|
||||||
strip-ansi "^5.1.0"
|
strip-ansi "^5.1.0"
|
||||||
|
|
||||||
|
string-width@^4.2.0:
|
||||||
|
version "4.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5"
|
||||||
|
integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==
|
||||||
|
dependencies:
|
||||||
|
emoji-regex "^8.0.0"
|
||||||
|
is-fullwidth-code-point "^3.0.0"
|
||||||
|
strip-ansi "^6.0.0"
|
||||||
|
|
||||||
string.prototype.trimend@^1.0.1:
|
string.prototype.trimend@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913"
|
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913"
|
||||||
@ -2372,10 +2399,10 @@ strip-ansi@^6.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ansi-regex "^5.0.0"
|
ansi-regex "^5.0.0"
|
||||||
|
|
||||||
strip-eof@^1.0.0:
|
strip-final-newline@^2.0.0:
|
||||||
version "1.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
|
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
||||||
integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
|
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
|
||||||
|
|
||||||
strip-json-comments@3.0.1:
|
strip-json-comments@3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
@ -2406,6 +2433,13 @@ supports-color@^5.3.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
has-flag "^3.0.0"
|
has-flag "^3.0.0"
|
||||||
|
|
||||||
|
supports-color@^7.2.0:
|
||||||
|
version "7.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
|
||||||
|
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
|
||||||
|
dependencies:
|
||||||
|
has-flag "^4.0.0"
|
||||||
|
|
||||||
symbol-observable@^1.1.0:
|
symbol-observable@^1.1.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
|
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
|
||||||
@ -2431,12 +2465,12 @@ throttleit@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c"
|
resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c"
|
||||||
integrity sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=
|
integrity sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=
|
||||||
|
|
||||||
tmp@~0.1.0:
|
tmp@~0.2.1:
|
||||||
version "0.1.0"
|
version "0.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877"
|
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
|
||||||
integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==
|
integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
rimraf "^2.6.3"
|
rimraf "^3.0.0"
|
||||||
|
|
||||||
to-regex-range@^5.0.1:
|
to-regex-range@^5.0.1:
|
||||||
version "5.0.1"
|
version "5.0.1"
|
||||||
@ -2499,10 +2533,10 @@ underscore@1.7.0:
|
|||||||
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209"
|
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209"
|
||||||
integrity sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=
|
integrity sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=
|
||||||
|
|
||||||
universalify@^0.1.0:
|
universalify@^2.0.0:
|
||||||
version "0.1.2"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
|
||||||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
|
||||||
|
|
||||||
untildify@^4.0.0:
|
untildify@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
@ -2560,13 +2594,6 @@ which@2.0.2, which@^2.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
isexe "^2.0.0"
|
isexe "^2.0.0"
|
||||||
|
|
||||||
which@^1.2.9:
|
|
||||||
version "1.3.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
|
|
||||||
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
|
|
||||||
dependencies:
|
|
||||||
isexe "^2.0.0"
|
|
||||||
|
|
||||||
wide-align@1.1.3:
|
wide-align@1.1.3:
|
||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
|
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
|
||||||
@ -2632,9 +2659,9 @@ xmlbuilder@>=0.4.2:
|
|||||||
integrity sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==
|
integrity sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==
|
||||||
|
|
||||||
y18n@^4.0.0:
|
y18n@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
|
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4"
|
||||||
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
|
integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==
|
||||||
|
|
||||||
yaml@0.2.3:
|
yaml@0.2.3:
|
||||||
version "0.2.3"
|
version "0.2.3"
|
||||||
|
Reference in New Issue
Block a user