Compare commits

..

No commits in common. "develop" and "v2.9.12" have entirely different histories.

65 changed files with 812 additions and 1207 deletions

View File

@ -1 +1 @@
2.9.19
2.9.12

5
Jenkinsfile vendored
View File

@ -62,13 +62,12 @@ pipeline {
stage('Backend') {
steps {
echo 'Checking Syntax ...'
sh 'docker pull nginxproxymanager/nginx-full:certbot-node'
// See: https://github.com/yarnpkg/yarn/issues/3254
sh '''docker run --rm \\
-v "$(pwd)/backend:/app" \\
-v "$(pwd)/global:/app/global" \\
-w /app \\
nginxproxymanager/nginx-full:certbot-node \\
node:latest \\
sh -c "yarn install && yarn eslint . && rm -rf node_modules"
'''
@ -221,7 +220,7 @@ pipeline {
}
post {
always {
sh 'docker-compose down --remove-orphans --volumes -t 30'
sh 'docker-compose down --rmi all --remove-orphans --volumes -t 30'
sh 'echo Reverting ownership'
sh 'docker run --rm -v $(pwd):/data jc21/ci-tools chown -R $(id -u):$(id -g) /data'
}

414
README.md
View File

@ -1,13 +1,22 @@
<p align="center">
<img src="https://nginxproxymanager.com/github.png">
<br><br>
<img src="https://img.shields.io/badge/version-2.9.19-green.svg?style=for-the-badge">
<img src="https://img.shields.io/badge/version-2.9.12-green.svg?style=for-the-badge">
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
<img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge">
</a>
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
<img src="https://img.shields.io/docker/pulls/jc21/nginx-proxy-manager.svg?style=for-the-badge">
</a>
<a href="https://ci.nginxproxymanager.com/blue/organizations/jenkins/nginx-proxy-manager/branches/">
<img src="https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fci.nginxproxymanager.com%2Fjob%2Fnginx-proxy-manager%2Fjob%2Fmaster&style=for-the-badge">
</a>
<a href="https://gitter.im/nginx-proxy-manager/community">
<img alt="Gitter" src="https://img.shields.io/gitter/room/nginx-proxy-manager/community?style=for-the-badge">
</a>
<a href="https://reddit.com/r/nginxproxymanager">
<img alt="Reddit" src="https://img.shields.io/reddit/subreddit-subscribers/nginxproxymanager?label=Reddit%20Community&style=for-the-badge">
</a>
</p>
This project comes as a pre-built docker image that enables you to easily forward to your websites
@ -74,10 +83,6 @@ services:
```bash
docker-compose up -d
# If using docker-compose-plugin
docker compose up -d
```
4. Log in to the Admin UI
@ -98,12 +103,395 @@ Immediately after logging in with this default user you will be asked to modify
## Contributors
Special thanks to [all of our contributors](https://github.com/NginxProxyManager/nginx-proxy-manager/graphs/contributors).
Special thanks to the following contributors:
## Getting Support
1. [Found a bug?](https://github.com/NginxProxyManager/nginx-proxy-manager/issues)
2. [Discussions](https://github.com/NginxProxyManager/nginx-proxy-manager/discussions)
3. [Development Gitter](https://gitter.im/nginx-proxy-manager/community)
4. [Reddit](https://reddit.com/r/nginxproxymanager)
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tr>
<td align="center">
<a href="https://github.com/Subv">
<img src="https://avatars1.githubusercontent.com/u/357072?s=460&u=d8adcdc91d749ae53e177973ed9b6bb6c4c894a3&v=4" width="80" alt=""/>
<br /><sub><b>Sebastian Valle</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/Indemnity83">
<img src="https://avatars3.githubusercontent.com/u/35218?s=460&u=7082004ff35138157c868d7d9c683ccebfce5968&v=4" width="80" alt=""/>
<br /><sub><b>Kyle Klaus</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/theraw">
<img src="https://avatars1.githubusercontent.com/u/32969774?s=460&u=6b359971e15685fb0359e6a8c065a399b40dc228&v=4" width="80" alt=""/>
<br /><sub><b>ƬHE ЯAW</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/spalger">
<img src="https://avatars2.githubusercontent.com/u/1329312?s=400&u=565223e38f1c052afb4c5dcca3fcf1c63ba17ae7&v=4" width="80" alt=""/>
<br /><sub><b>Spencer</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/Xantios">
<img src="https://avatars3.githubusercontent.com/u/1507836?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Xantios Krugor</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/dpanesso">
<img src="https://avatars2.githubusercontent.com/u/2687121?s=460&v=4" width="80" alt=""/>
<br /><sub><b>David Panesso</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/IronTooch">
<img src="https://avatars3.githubusercontent.com/u/27360514?s=460&u=69bf854a6647c55725f62ecb8d39249c6c0b2602&v=4" width="80" alt=""/>
<br /><sub><b>IronTooch</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://github.com/damianog">
<img src="https://avatars1.githubusercontent.com/u/2786682?s=460&u=76c6136fae797abb76b951cd8a246dcaecaf21af&v=4" width="80" alt=""/>
<br /><sub><b>Damiano</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/tfmm">
<img src="https://avatars3.githubusercontent.com/u/6880538?s=460&u=ce0160821cc4aa802df8395200f2d4956a5bc541&v=4" width="80" alt=""/>
<br /><sub><b>Russ</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/margaale">
<img src="https://avatars3.githubusercontent.com/u/20794934?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Marcelo Castagna</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/Steven-Harris">
<img src="https://avatars2.githubusercontent.com/u/7720242?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Steven Harris</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/jlesage">
<img src="https://avatars0.githubusercontent.com/u/1791123?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Jocelyn Le Sage</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/cmer">
<img src="https://avatars0.githubusercontent.com/u/412?s=460&u=67dd8b2e3661bfd6f68ec1eaa5b9821bd8a321cd&v=4" width="80" alt=""/>
<br /><sub><b>Carl Mercier</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/the1ts">
<img src="https://avatars1.githubusercontent.com/u/84956?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Paul Mansfield</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://github.com/OhHeyAlan">
<img src="https://avatars0.githubusercontent.com/u/11955126?s=460&u=fbaa5a1a4f73ef8960132c703349bfd037fe2630&v=4" width="80" alt=""/>
<br /><sub><b>OhHeyAlan</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/dogmatic69">
<img src="https://avatars2.githubusercontent.com/u/94674?s=460&u=ca7647de53145c6283b6373ade5dc94ba99347db&v=4" width="80" alt=""/>
<br /><sub><b>Carl Sutton</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/tg44">
<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>
</a>
</td>
<td align="center">
<a href="https://github.com/vrenjith">
<img src="https://avatars3.githubusercontent.com/u/2093241?s=460&u=96ce93a9bebabdd0a60a2dc96cd093a41d5edaba&v=4" width="80" alt=""/>
<br /><sub><b>vrenjith</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/duhruh">
<img src="https://avatars2.githubusercontent.com/u/1133969?s=460&u=c0691e6131ec6d516416c1c6fcedb5034f877bbe&v=4" width="80" alt=""/>
<br /><sub><b>David Rivera</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/jipjan">
<img src="https://avatars2.githubusercontent.com/u/1384618?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Jaap-Jan de Wit</b></sub>
</a>
</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>
<td align="center">
<a href="https://github.com/bikram990">
<img src="https://avatars.githubusercontent.com/u/6782131?v=4" width="80" alt=""/>
<br /><sub><b>Bikramjeet Singh</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/razvanstoica89">
<img src="https://avatars.githubusercontent.com/u/28236583?v=4" width="80" alt=""/>
<br /><sub><b>Razvan Stoica</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/psharma04">
<img src="https://avatars.githubusercontent.com/u/22587474?v=4" width="80" alt=""/>
<br /><sub><b>RBXII3</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/demize">
<img src="https://avatars.githubusercontent.com/u/264914?v=4" width="80" alt=""/>
<br /><sub><b>demize</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/PUP-Loki">
<img src="https://avatars.githubusercontent.com/u/75944209?v=4" width="80" alt=""/>
<br /><sub><b>PUP-Loki</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/DSorlov">
<img src="https://avatars.githubusercontent.com/u/8133650?v=4" width="80" alt=""/>
<br /><sub><b>Daniel Sörlöv</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://github.com/Theyooo">
<img src="https://avatars.githubusercontent.com/u/58510131?v=4" width="80" alt=""/>
<br /><sub><b>Theyooo</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/mrdink">
<img src="https://avatars.githubusercontent.com/u/514751?v=4" width="80" alt=""/>
<br /><sub><b>Justin Peacock</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/ChrisTracy">
<img src="https://avatars.githubusercontent.com/u/58871574?v=4" width="80" alt=""/>
<br /><sub><b>Chris Tracy</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/Fuechslein">
<img src="https://avatars.githubusercontent.com/u/15112818?v=4" width="80" alt=""/>
<br /><sub><b>Fuechslein</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/nightah">
<img src="https://avatars.githubusercontent.com/u/3339418?v=4" width="80" alt=""/>
<br /><sub><b>Amir Zarrinkafsh</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/gabbe">
<img src="https://avatars.githubusercontent.com/u/156397?v=4" width="80" alt=""/>
<br /><sub><b>gabbe</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bmbvenom">
<img src="https://avatars.githubusercontent.com/u/20530371?v=4" width="80" alt=""/>
<br /><sub><b>bmbvenom</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://github.com/FMeinicke">
<img src="https://avatars.githubusercontent.com/u/42121639?v=4" width="80" alt=""/>
<br /><sub><b>Florian Meinicke</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/ssrahul96">
<img src="https://avatars.githubusercontent.com/u/15570570?v=4" width="80" alt=""/>
<br /><sub><b>Rahul Somasundaram</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/BjoernAkAManf">
<img src="https://avatars.githubusercontent.com/u/833043?v=4" width="80" alt=""/>
<br /><sub><b>Björn Heinrichs</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/realJoshByrnes">
<img src="https://avatars.githubusercontent.com/u/204185?v=4" width="80" alt=""/>
<br /><sub><b>Josh Byrnes</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bergi9">
<img src="https://avatars.githubusercontent.com/u/5556750?v=4" width="80" alt=""/>
<br /><sub><b>bergi9</b></sub>
</a>
</td>
</tr>
</table>
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->

View File

@ -1,6 +1,5 @@
const _ = require('lodash');
const fs = require('fs');
const https = require('https');
const tempWrite = require('temp-write');
const moment = require('moment');
const logger = require('../logger').ssl;
@ -16,7 +15,6 @@ const letsencryptConfig = '/etc/letsencrypt.ini';
const certbotCommand = 'certbot';
const archiver = require('archiver');
const path = require('path');
const { isArray } = require('lodash');
function omissions() {
return ['is_deleted'];
@ -171,7 +169,6 @@ const internalCertificate = {
// 3. Generate the LE config
return internalNginx.generateLetsEncryptRequestConfig(certificate)
.then(internalNginx.reload)
.then(async() => await new Promise((r) => setTimeout(r, 5000)))
.then(() => {
// 4. Request cert
return internalCertificate.requestLetsEncryptSsl(certificate);
@ -477,7 +474,7 @@ const internalCertificate = {
// Query is used for searching
if (typeof search_query === 'string') {
query.where(function () {
this.where('nice_name', 'like', '%' + search_query + '%');
this.where('name', 'like', '%' + search_query + '%');
});
}
@ -871,15 +868,8 @@ const internalCertificate = {
logger.info(`Requesting Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
const credentialsLocation = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
// Escape single quotes and backslashes
const escapedCredentials = certificate.meta.dns_provider_credentials.replaceAll('\'', '\\\'').replaceAll('\\', '\\\\');
const credentialsCmd = 'mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo \'' + escapedCredentials + '\' > \'' + credentialsLocation + '\' && chmod 600 \'' + credentialsLocation + '\'';
let prepareCmd = 'pip install ' + dns_plugin.package_name + (dns_plugin.version_requirement || '') + ' ' + dns_plugin.dependencies;
// Special case for cloudflare
if (dns_plugin.package_name === 'certbot-dns-cloudflare') {
prepareCmd = 'pip install certbot-dns-cloudflare --index-url https://www.piwheels.org/simple --prefer-binary';
}
const credentialsCmd = 'mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo \'' + certificate.meta.dns_provider_credentials.replace('\'', '\\\'') + '\' > \'' + credentialsLocation + '\' && chmod 600 \'' + credentialsLocation + '\'';
const prepareCmd = 'pip install ' + dns_plugin.package_name + (dns_plugin.version_requirement || '') + ' ' + dns_plugin.dependencies;
// Whether the plugin has a --<name>-credentials argument
const hasConfigArg = certificate.meta.dns_provider !== 'route53';
@ -1134,94 +1124,6 @@ const internalCertificate = {
} else {
return Promise.resolve();
}
},
testHttpsChallenge: async (access, domains) => {
await access.can('certificates:list');
if (!isArray(domains)) {
throw new error.InternalValidationError('Domains must be an array of strings');
}
if (domains.length === 0) {
throw new error.InternalValidationError('No domains provided');
}
// Create a test challenge file
const testChallengeDir = '/data/letsencrypt-acme-challenge/.well-known/acme-challenge';
const testChallengeFile = testChallengeDir + '/test-challenge';
fs.mkdirSync(testChallengeDir, {recursive: true});
fs.writeFileSync(testChallengeFile, 'Success', {encoding: 'utf8'});
async function performTestForDomain (domain) {
logger.info('Testing http challenge for ' + domain);
const url = `http://${domain}/.well-known/acme-challenge/test-challenge`;
const formBody = `method=G&url=${encodeURI(url)}&bodytype=T&requestbody=&headername=User-Agent&headervalue=None&locationid=1&ch=false&cc=false`;
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(formBody)
}
};
const result = await new Promise((resolve) => {
const req = https.request('https://www.site24x7.com/tools/restapi-tester', options, function (res) {
let responseBody = '';
res.on('data', (chunk) => responseBody = responseBody + chunk);
res.on('end', function () {
const parsedBody = JSON.parse(responseBody + '');
if (res.statusCode !== 200) {
logger.warn(`Failed to test HTTP challenge for domain ${domain}`, res);
resolve(undefined);
}
resolve(parsedBody);
});
});
// Make sure to write the request body.
req.write(formBody);
req.end();
req.on('error', function (e) { logger.warn(`Failed to test HTTP challenge for domain ${domain}`, e);
resolve(undefined); });
});
if (!result) {
// Some error occurred while trying to get the data
return 'failed';
} else if (`${result.responsecode}` === '200' && result.htmlresponse === 'Success') {
// Server exists and has responded with the correct data
return 'ok';
} else if (`${result.responsecode}` === '200') {
// Server exists but has responded with wrong data
logger.info(`HTTP challenge test failed for domain ${domain} because of invalid returned data:`, result.htmlresponse);
return 'wrong-data';
} else if (`${result.responsecode}` === '404') {
// Server exists but responded with a 404
logger.info(`HTTP challenge test failed for domain ${domain} because code 404 was returned`);
return '404';
} else if (`${result.responsecode}` === '0' || (typeof result.reason === 'string' && result.reason.toLowerCase() === 'host unavailable')) {
// Server does not exist at domain
logger.info(`HTTP challenge test failed for domain ${domain} the host was not found`);
return 'no-host';
} else {
// Other errors
logger.info(`HTTP challenge test failed for domain ${domain} because code ${result.responsecode} was returned`);
return `other:${result.responsecode}`;
}
}
const results = {};
for (const domain of domains){
results[domain] = await performTestForDomain(domain);
}
// Remove the test challenge file
fs.unlinkSync(testChallengeFile);
return results;
}
};

View File

@ -9,9 +9,6 @@ const CLOUDFRONT_URL = 'https://ip-ranges.amazonaws.com/ip-ranges.json';
const CLOUDFARE_V4_URL = 'https://www.cloudflare.com/ips-v4';
const CLOUDFARE_V6_URL = 'https://www.cloudflare.com/ips-v6';
const regIpV4 = /^(\d+\.?){4}\/\d+/;
const regIpV6 = /^(([\da-fA-F]+)?:)+\/\d+/;
const internalIpRanges = {
interval_timeout: 1000 * 60 * 60 * 6, // 6 hours
@ -77,14 +74,14 @@ const internalIpRanges = {
return internalIpRanges.fetchUrl(CLOUDFARE_V4_URL);
})
.then((cloudfare_data) => {
let items = cloudfare_data.split('\n').filter((line) => regIpV4.test(line));
let items = cloudfare_data.split('\n');
ip_ranges = [... ip_ranges, ... items];
})
.then(() => {
return internalIpRanges.fetchUrl(CLOUDFARE_V6_URL);
})
.then((cloudfare_data) => {
let items = cloudfare_data.split('\n').filter((line) => regIpV6.test(line));
let items = cloudfare_data.split('\n');
ip_ranges = [... ip_ranges, ... items];
})
.then(() => {

View File

@ -1,50 +0,0 @@
const migrate_name = 'stream_domain';
const logger = require('../logger').migrate;
const internalNginx = require('../internal/nginx');
async function regenerateDefaultHost(knex) {
const row = await knex('setting').select('*').where('id', 'default-site').first();
if (!row) {
return Promise.resolve();
}
return internalNginx.deleteConfig('default')
.then(() => {
return internalNginx.generateConfig('default', row);
})
.then(() => {
return internalNginx.test();
})
.then(() => {
return internalNginx.reload();
});
}
/**
* Migrate
*
* @see http://knexjs.org/#Schema
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.up = function (knex) {
logger.info('[' + migrate_name + '] Migrating Up...');
return regenerateDefaultHost(knex);
};
/**
* Undo Migrate
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.down = function (knex) {
logger.info('[' + migrate_name + '] Migrating Down...');
return regenerateDefaultHost(knex);
};

View File

@ -19,7 +19,7 @@
"knex": "^0.20.13",
"liquidjs": "^9.11.10",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"moment": "^2.24.0",
"mysql": "^2.18.1",
"node-rsa": "^1.0.8",
"nodemon": "^2.0.2",

View File

@ -68,32 +68,6 @@ router
.catch(next);
});
/**
* Test HTTP challenge for domains
*
* /api/nginx/certificates/test-http
*/
router
.route('/test-http')
.options((req, res) => {
res.sendStatus(204);
})
.all(jwtdecode())
/**
* GET /api/nginx/certificates/test-http
*
* Test HTTP challenge for domains
*/
.get((req, res, next) => {
internalCertificate.testHttpsChallenge(res.locals.access, JSON.parse(req.query.domains))
.then((result) => {
res.status(200)
.send(result);
})
.catch(next);
});
/**
* Specific certificate
*
@ -235,6 +209,7 @@ router
.catch(next);
});
/**
* Download LE Certs
*

View File

@ -157,17 +157,6 @@
"targetSchema": {
"type": "boolean"
}
},
{
"title": "Test HTTP Challenge",
"description": "Tests whether the HTTP challenge should work",
"href": "/nginx/certificates/{definitions.identity.example}/test-http",
"access": "private",
"method": "GET",
"rel": "info",
"http_header": {
"$ref": "../examples.json#/definitions/auth_header"
}
}
]
}

View File

@ -171,24 +171,17 @@ const setupCertbotPlugins = () => {
if (certificates && certificates.length) {
let plugins = [];
let promises = [];
let install_cloudflare_plugin = false;
certificates.map(function (certificate) {
if (certificate.meta && certificate.meta.dns_challenge === true) {
const dns_plugin = dns_plugins[certificate.meta.dns_provider];
if (dns_plugin.package_name === 'certbot-dns-cloudflare') {
install_cloudflare_plugin = true;
} else {
const packages_to_install = `${dns_plugin.package_name}${dns_plugin.version_requirement || ''} ${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;
// Escape single quotes and backslashes
const escapedCredentials = certificate.meta.dns_provider_credentials.replaceAll('\'', '\\\'').replaceAll('\\', '\\\\');
const credentials_cmd = '[ -f \'' + credentials_loc + '\' ] || { mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo \'' + escapedCredentials + '\' > \'' + credentials_loc + '\' && chmod 600 \'' + credentials_loc + '\'; }';
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));
}
});
@ -198,10 +191,6 @@ const setupCertbotPlugins = () => {
promises.push(utils.exec(install_cmd));
}
if (install_cloudflare_plugin) {
promises.push(utils.exec('pip install certbot-dns-cloudflare --index-url https://www.piwheels.org/simple --prefer-binary'));
}
if (promises.length) {
return Promise.all(promises)
.then(() => {

View File

@ -1,10 +1,16 @@
location {{ path }} {
set $targetUri {{ forward_scheme }}://{{ forward_host }}:{{ forward_port }}{{ forward_path }};
{% unless path contains "~" and path contains "(" and path contains ")" %}
if ($request_uri != /){
set $targetUri $targetUri$request_uri;
}
{% endunless %}
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass {{ forward_scheme }}://{{ forward_host }}:{{ forward_port }}{{ forward_path }};
proxy_pass $targetUri;
{% if access_list_id > 0 %}
{% if access_list.items.length > 0 %}

View File

@ -7,9 +7,9 @@
server {
listen 80 default;
{% if ipv6 -%}
listen [::]:80 default;
listen [::]:80;
{% else -%}
#listen [::]:80 default;
#listen [::]:80;
{% endif %}
server_name default-host.localhost;
access_log /data/logs/default-host_access.log combined;

View File

@ -246,9 +246,9 @@ astral-regex@^1.0.0:
integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
async@^3.2.0:
version "3.2.4"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c"
integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==
version "3.2.1"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.1.tgz#d3274ec66d107a47476a4c49136aacdb00665fc8"
integrity sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==
atob@^2.1.2:
version "2.1.2"
@ -2271,10 +2271,10 @@ mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5:
dependencies:
minimist "^1.2.5"
moment@^2.29.4:
version "2.29.4"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
moment@^2.24.0:
version "2.27.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d"
integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==
ms@2.0.0:
version "2.0.0"

View File

@ -3,7 +3,7 @@
# This file assumes that the frontend has been built using ./scripts/frontend-build
FROM nginxproxymanager/nginx-full:certbot-node
FROM nginxproxymanager/nginx-full:node
ARG TARGETPLATFORM
ARG BUILD_VERSION
@ -46,11 +46,6 @@ RUN rm -rf /etc/services.d/frontend /etc/nginx/conf.d/dev.conf
# Change permission of logrotate config file
RUN chmod 644 /etc/logrotate.d/nginx-proxy-manager
# fix for pip installs
# https://github.com/NginxProxyManager/nginx-proxy-manager/issues/1769
RUN pip uninstall --yes setuptools \
&& pip install "setuptools==58.0.0"
VOLUME [ "/data", "/etc/letsencrypt" ]
ENTRYPOINT [ "/init" ]

View File

@ -1,4 +1,4 @@
FROM nginxproxymanager/nginx-full:certbot-node
FROM nginxproxymanager/nginx-full:node
LABEL maintainer="Jamie Curnow <jc@jc21.com>"
ENV S6_LOGGING=0 \

View File

@ -2,7 +2,7 @@
# 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
# search through full-path filenames for files ending in "__FILE"
# 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##*/} ..."

View File

@ -30,7 +30,7 @@ server {
set $port "443";
server_name localhost;
access_log /data/logs/fallback_access.log standard;
access_log /data/logs/fallback-access.log standard;
error_log /dev/null crit;
ssl_certificate /data/nginx/dummycert.pem;
ssl_certificate_key /data/nginx/dummykey.pem;

View File

@ -1,4 +1,4 @@
location ~* ^.*\.(css|js|jpe?g|gif|png|webp|woff|eot|ttf|svg|ico|css\.map|js\.map)$ {
location ~* ^.*\.(css|js|jpe?g|gif|png|woff|eot|ttf|svg|ico|css\.map|js\.map)$ {
if_modified_since off;
# use the public cache

View File

@ -1,8 +1,9 @@
set $targetUri $forward_scheme://$server:$port$request_uri;
add_header X-Served-By $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass $forward_scheme://$server:$port$request_uri;
proxy_pass $targetUri;

View File

@ -24,12 +24,8 @@ chown root /tmp/nginx
# Dynamically generate resolvers file, if resolver is IPv6, enclose in `[]`
# thanks @tfmm
if [ "$DISABLE_IPV6" == "true" ] || [ "$DISABLE_IPV6" == "on" ] || [ "$DISABLE_IPV6" == "1" ] || [ "$DISABLE_IPV6" == "yes" ];
then
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf) ipv6=off valid=10s;" > /etc/nginx/conf.d/include/resolvers.conf
else
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf) valid=10s;" > /etc/nginx/conf.d/include/resolvers.conf
fi
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" > /etc/nginx/conf.d/include/resolvers.conf
# Generate dummy self-signed certificate.
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]
then

View File

@ -18,7 +18,7 @@ services running on this Docker host:
```yml
networks:
default:
external: true
external:
name: scoobydoo
```
@ -38,7 +38,7 @@ services:
networks:
default:
external: true
external:
name: scoobydoo
```

View File

@ -21,6 +21,3 @@ Your best bet is to ask the [Reddit community for support](https://www.reddit.co
Gitter is best left for anyone contributing to the project to ask for help about internals, code reviews etc.
## When adding username and password access control to a proxy host, I can no longer login into the app.
Having an Access Control List (ACL) with username and password requires the browser to always send this username and password in the `Authorization` header on each request. If your proxied app also requires authentication (like Nginx Proxy Manager itself), most likely the app will also use the `Authorization` header to transmit this information, as this is the standardized header meant for this kind of information. However having multiples of the same headers is not allowed in the [internet standard](https://www.rfc-editor.org/rfc/rfc7230#section-3.2.2) and almost all apps do not support multiple values in the `Authorization` header. Hence one of the two logins will be broken. This can only be fixed by either removing one of the logins or by changing the app to use other non-standard headers for authorization.

View File

@ -213,7 +213,7 @@
"etag": "^1.8.1",
"eventemitter3": "^4.0.4",
"events": "^3.2.0",
"eventsource": "^2.0.2",
"eventsource": "^1.0.7",
"evp_bytestokey": "^1.0.3",
"execa": "^4.0.3",
"expand-brackets": "^4.0.0",
@ -357,7 +357,7 @@
"jsbn": "^1.1.0",
"jsesc": "^3.0.1",
"json-parse-better-errors": "^1.0.2",
"json-schema": "^0.4.0",
"json-schema": "^0.2.5",
"json-schema-traverse": "^0.4.1",
"json-stringify-safe": "^5.0.1",
"json3": "^3.3.3",
@ -394,7 +394,7 @@
"map-age-cleaner": "^0.1.3",
"map-cache": "^0.2.2",
"map-visit": "^1.0.0",
"markdown-it": "^12.3.2",
"markdown-it": "^11.0.0",
"markdown-it-anchor": "^5.3.0",
"markdown-it-chain": "^1.3.0",
"markdown-it-container": "^3.0.0",
@ -434,7 +434,7 @@
"neo-async": "^2.6.2",
"nice-try": "^2.0.1",
"no-case": "^3.0.3",
"node-forge": "^1.0.0",
"node-forge": "^0.10.0",
"node-libs-browser": "^2.2.1",
"node-releases": "^1.1.60",
"nopt": "^4.0.3",

View File

@ -107,7 +107,7 @@ you don't have to worry about doing anything special and you can follow the comm
Check out the [dockerhub tags](https://hub.docker.com/r/jc21/nginx-proxy-manager/tags)
for a list of supported architectures and if you want one that doesn't exist,
[create a feature request](https://github.com/NginxProxyManager/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=).
[create a feature request](https://github.com/jc21/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=).
Also, if you don't know how to already, follow [this guide to install docker and docker-compose](https://manre-universe.net/how-to-run-docker-and-docker-compose-on-raspbian/)
on Raspbian.

View File

@ -1,6 +1,6 @@
# Third Party
As this software gains popularity it's common to see it integrated with other platforms. Please be aware that unless specifically mentioned in the documentation of those
As this software gains popularity it's common to see it integrated with other platforms. Please be aware that unless specifically mentioned in the documenation of those
integrations, they are *not supported* by me.
Known integrations:

View File

@ -967,46 +967,6 @@
lodash "^4.17.19"
to-fast-properties "^2.0.0"
"@jridgewell/gen-mapping@^0.3.0":
version "0.3.2"
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==
dependencies:
"@jridgewell/set-array" "^1.0.1"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@jridgewell/trace-mapping" "^0.3.9"
"@jridgewell/resolve-uri@^3.0.3":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
"@jridgewell/set-array@^1.0.1":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
"@jridgewell/source-map@^0.3.2":
version "0.3.2"
resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb"
integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==
dependencies:
"@jridgewell/gen-mapping" "^0.3.0"
"@jridgewell/trace-mapping" "^0.3.9"
"@jridgewell/sourcemap-codec@^1.4.10":
version "1.4.14"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
"@jridgewell/trace-mapping@^0.3.9":
version "0.3.14"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed"
integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==
dependencies:
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@mrmlnc/readdir-enhanced@^2.2.1":
version "2.2.1"
resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
@ -1536,11 +1496,6 @@ acorn@^7.4.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c"
integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==
acorn@^8.5.0:
version "8.7.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30"
integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==
agentkeepalive@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-2.2.0.tgz#c5d1bd4b129008f1163f236f86e5faea2026e2ef"
@ -1731,11 +1686,6 @@ argparse@^1.0.10, argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
arr-diff@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
@ -3794,10 +3744,10 @@ entities@^1.1.1, entities@~1.1.1:
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
entities@^2.0.0, entities@^2.0.3, entities@~2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==
entities@^2.0.0, entities@^2.0.3, entities@~2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f"
integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==
envify@^4.0.0, envify@^4.1.0:
version "4.1.0"
@ -3975,11 +3925,6 @@ eventsource@^1.0.7:
dependencies:
original "^1.0.0"
eventsource@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-2.0.2.tgz#76dfcc02930fb2ff339520b6d290da573a9e8508"
integrity sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==
evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
@ -4167,13 +4112,6 @@ fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0:
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
fast-xml-parser@^3.19.0:
version "3.21.1"
resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.21.1.tgz#152a1d51d445380f7046b304672dd55d15c9e736"
integrity sha512-FTFVjYoBOZTJekiUsawGsSYV9QL0A+zDYCRj7y34IO6Jg+2IMYEtQa+bbictpdpV8dHxXywqU7C0gRDEOFtBFg==
dependencies:
strnum "^1.0.4"
fastq@^1.6.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481"
@ -4316,9 +4254,9 @@ flush-write-stream@^2.0.0:
readable-stream "^3.1.1"
follow-redirects@^1.0.0, follow-redirects@^1.12.1:
version "1.14.8"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc"
integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==
version "1.12.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.12.1.tgz#de54a6205311b93d60398ebc01cf7015682312b6"
integrity sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg==
for-in@^1.0.2:
version "1.0.2"
@ -5592,11 +5530,11 @@ is-svg@^3.0.0:
html-comment-regex "^1.1.0"
is-svg@^4.2.1:
version "4.3.0"
resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-4.3.0.tgz#3e46a45dcdb2780e42a3c8538154d7f7bfc07216"
integrity sha512-Np3TOGLVr0J27VDaS/gVE7bT45ZcSmX4pMmMTsPjqO8JY383fuPIcWmZr3QsHVWhqhZWxSdmW+tkkl3PWOB0Nw==
version "4.2.2"
resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-4.2.2.tgz#a4ea0f3f78dada7085db88f1e85b6f845626cfae"
integrity sha512-JlA7Mc7mfWjdxxTkJ094oUK9amGD7gQaj5xA/NCY0vlVvZ1stmj4VX+bRuwOMN93IHRZ2ctpPH/0FO6DqvQ5Rw==
dependencies:
fast-xml-parser "^3.19.0"
html-comment-regex "^1.1.2"
is-symbol@^1.0.2, is-symbol@^1.0.3:
version "1.0.3"
@ -5776,10 +5714,10 @@ json-schema@0.2.3:
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-schema@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-schema@^0.2.5:
version "0.2.5"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.5.tgz#97997f50972dd0500214e208c407efa4b5d7063b"
integrity sha512-gWJOWYFrhQ8j7pVm0EM8Slr+EPVq1Phf6lvzvD/WCeqkrx/f2xBI0xOsRRS9xCn3I4vKtP519dvs3TP09r24wQ==
json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
version "5.0.1"
@ -5977,9 +5915,9 @@ loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4
json5 "^1.0.1"
loader-utils@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.3.tgz#d4b15b8504c63d1fc3f2ade52d41bc8459d6ede1"
integrity sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==
version "2.0.0"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0"
integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==
dependencies:
big.js "^5.2.2"
emojis-list "^3.0.0"
@ -6197,13 +6135,13 @@ markdown-it-table-of-contents@^0.4.0, markdown-it-table-of-contents@^0.4.4:
resolved "https://registry.yarnpkg.com/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.4.4.tgz#3dc7ce8b8fc17e5981c77cc398d1782319f37fbc"
integrity sha512-TAIHTHPwa9+ltKvKPWulm/beozQU41Ab+FIefRaQV1NRnpzwcV9QOe6wXQS5WLivm5Q/nlo0rl6laGkMDZE7Gw==
markdown-it@^12.3.2:
version "12.3.2"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90"
integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==
markdown-it@^11.0.0:
version "11.0.0"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-11.0.0.tgz#dbfc30363e43d756ebc52c38586b91b90046b876"
integrity sha512-+CvOnmbSubmQFSA9dKz1BRiaSMV7rhexl3sngKqFyXSagoA3fBdJQ8oZWtRy2knXdpDXaBw44euz37DeJQ9asg==
dependencies:
argparse "^2.0.1"
entities "~2.1.0"
argparse "^1.0.7"
entities "~2.0.0"
linkify-it "^3.0.1"
mdurl "^1.0.1"
uc.micro "^1.0.5"
@ -6657,10 +6595,10 @@ node-forge@0.9.0:
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579"
integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==
node-forge@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.0.0.tgz#a025e3beeeb90d9cee37dae34d25b968ec3e6f15"
integrity sha512-ShkiiAlzSsgH1IwGlA0jybk9vQTIOLyJ9nBd0JTuP+nzADJFLY0NoDijM2zvD/JaezooGu3G2p2FNxOAK6459g==
node-forge@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==
node-libs-browser@^2.2.1:
version "2.2.1"
@ -7768,9 +7706,9 @@ pretty-time@^1.1.0:
integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==
prismjs@^1.13.0, prismjs@^1.20.0:
version "1.27.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057"
integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==
version "1.25.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.25.0.tgz#6f822df1bdad965734b310b315a23315cf999756"
integrity sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg==
private@^0.1.8:
version "0.1.8"
@ -8816,10 +8754,10 @@ source-map-resolve@^0.6.0:
atob "^2.1.2"
decode-uri-component "^0.2.0"
source-map-support@^0.5.19, source-map-support@~0.5.12, source-map-support@~0.5.20:
version "0.5.21"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
source-map-support@^0.5.19, source-map-support@~0.5.12:
version "0.5.19"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
dependencies:
buffer-from "^1.0.0"
source-map "^0.6.0"
@ -9142,11 +9080,6 @@ strip-json-comments@~2.0.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
strnum@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db"
integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==
stylehacks@^4.0.0, stylehacks@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5"
@ -9291,14 +9224,13 @@ terser@^4.1.2:
source-map-support "~0.5.12"
terser@^5.0.0:
version "5.14.2"
resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10"
integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==
version "5.0.0"
resolved "https://registry.yarnpkg.com/terser/-/terser-5.0.0.tgz#269640e4e92f15d628de1e5f01c4c61e1ba3d765"
integrity sha512-olH2DwGINoSuEpSGd+BsPuAQaA3OrHnHnFL/rDB2TVNc3srUbz/rq/j2BlF4zDXI+JqAvGr86bIm1R2cJgZ3FA==
dependencies:
"@jridgewell/source-map" "^0.3.2"
acorn "^8.5.0"
commander "^2.20.0"
source-map-support "~0.5.20"
source-map "~0.6.1"
source-map-support "~0.5.12"
text-table@^0.2.0:
version "0.2.0"
@ -9732,9 +9664,9 @@ url-parse-lax@^3.0.0:
prepend-http "^2.0.0"
url-parse@^1.4.3, url-parse@^1.4.7:
version "1.5.9"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.9.tgz#05ff26484a0b5e4040ac64dcee4177223d74675e"
integrity sha512-HpOvhKBvre8wYez+QhHcYiVvVmeF6DVnuSOOPhe3cTum3BnqHhvKaZm8FU5yTiOu/Jut2ZpB2rA/SbBA1JIGlQ==
version "1.5.2"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.2.tgz#a4eff6fd5ff9fe6ab98ac1f79641819d13247cda"
integrity sha512-6bTUPERy1muxxYClbzoRo5qtQuyoGEbzbQvi0SW4/8U8UyVkAQhWFBlnigqJkRm4su4x1zDQfNbEzWkt+vchcg==
dependencies:
querystringify "^2.1.1"
requires-port "^1.0.0"

View File

@ -685,16 +685,6 @@ module.exports = {
return fetch('post', 'nginx/certificates/' + id + '/renew', undefined, {timeout});
},
/**
* @param {Number} id
* @returns {Promise}
*/
testHttpChallenge: function (domains) {
return fetch('get', 'nginx/certificates/test-http?' + new URLSearchParams({
domains: JSON.stringify(domains),
}));
},
/**
* @param {Number} id
* @returns {Promise}

View File

@ -2,16 +2,6 @@
<div class="card-status bg-teal"></div>
<div class="card-header">
<h3 class="card-title"><%- i18n('audit-log', 'title') %></h3>
<div class="card-options">
<form class="search-form" role="search">
<div class="input-icon">
<span class="input-icon-addon">
<i class="fe fe-search"></i>
</span>
<input name="source-query" type="text" value="" class="form-control form-control-sm" placeholder="<%- i18n('audit-log', 'search') %>" aria-label="<%- i18n('audit-log', 'search') %>">
</div>
</form>
</div>
</div>
<div class="card-body no-padding min-100">
<div class="dimmer active">

View File

@ -12,21 +12,31 @@ module.exports = Mn.View.extend({
ui: {
list_region: '.list-region',
dimmer: '.dimmer',
search: '.search-form',
query: 'input[name="source-query"]'
dimmer: '.dimmer'
},
fetch: App.Api.AuditLog.getAll,
regions: {
list_region: '@ui.list_region'
},
showData: function(response) {
this.showChildView('list_region', new ListView({
onRender: function () {
let view = this;
App.Api.AuditLog.getAll(['user'])
.then(response => {
if (!view.isDestroyed() && response && response.length) {
view.showChildView('list_region', new ListView({
collection: new AuditLogModel.Collection(response)
}));
},
showError: function(err) {
this.showChildView('list_region', new ErrorView({
} else {
view.showChildView('list_region', new EmptyView({
title: App.i18n('audit-log', 'empty'),
subtitle: App.i18n('audit-log', 'empty-subtitle')
}));
}
})
.catch(err => {
view.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
@ -35,45 +45,6 @@ module.exports = Mn.View.extend({
}));
console.error(err);
},
showEmpty: function() {
this.showChildView('list_region', new EmptyView({
title: App.i18n('audit-log', 'empty'),
subtitle: App.i18n('audit-log', 'empty-subtitle')
}));
},
regions: {
list_region: '@ui.list_region'
},
events: {
'submit @ui.search': function (e) {
e.preventDefault();
let query = this.ui.query.val();
this.fetch(['user'], query)
.then(response => this.showData(response))
.catch(err => {
this.showError(err);
});
}
},
onRender: function () {
let view = this;
view.fetch(['user'])
.then(response => {
if (!view.isDestroyed() && response && response.length) {
view.showData(response);
} else {
view.showEmpty();
}
})
.catch(err => {
view.showError(err);
})
.then(() => {
view.ui.dimmer.removeClass('active');

View File

@ -366,19 +366,6 @@ module.exports = {
}
},
/**
* Certificate Test Reachability
*
* @param model
*/
showNginxCertificateTestReachability: function (model) {
if (Cache.User.isAdmin() || Cache.User.canManage('certificates')) {
require(['./main', './nginx/certificates/test'], function (App, View) {
App.UI.showModalDialog(new View({model: model}));
});
}
},
/**
* Audit Log
*/

View File

@ -3,14 +3,6 @@
<div class="card-header">
<h3 class="card-title"><%- i18n('access-lists', 'title') %></h3>
<div class="card-options">
<form class="search-form" role="search">
<div class="input-icon">
<span class="input-icon-addon">
<i class="fe fe-search"></i>
</span>
<input name="source-query" type="text" value="" class="form-control form-control-sm" placeholder="<%- i18n('access-lists', 'search') %>" aria-label="<%- i18n('access-lists', 'search') %>">
</div>
</form>
<a href="#" class="btn btn-outline-secondary btn-sm ml-2 help"><i class="fe fe-help-circle"></i></a>
<% if (showAddButton) { %>
<a href="#" class="btn btn-outline-teal btn-sm ml-2 add-item"><%- i18n('access-lists', 'add') %></a>

View File

@ -14,44 +14,7 @@ module.exports = Mn.View.extend({
list_region: '.list-region',
add: '.add-item',
help: '.help',
dimmer: '.dimmer',
search: '.search-form',
query: 'input[name="source-query"]'
},
fetch: App.Api.Nginx.AccessLists.getAll,
showData: function(response) {
this.showChildView('list_region', new ListView({
collection: new AccessListModel.Collection(response)
}));
},
showError: function(err) {
this.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showNginxAccess();
}
}));
console.error(err);
},
showEmpty: function() {
let manage = App.Cache.User.canManage('access_lists');
this.showChildView('list_region', new EmptyView({
title: App.i18n('access-lists', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('access-lists', 'add') : null,
btn_color: 'teal',
permission: 'access_lists',
action: function () {
App.Controller.showNginxAccessListForm();
}
}));
dimmer: '.dimmer'
},
regions: {
@ -67,17 +30,6 @@ module.exports = Mn.View.extend({
'click @ui.help': function (e) {
e.preventDefault();
App.Controller.showHelp(App.i18n('access-lists', 'help-title'), App.i18n('access-lists', 'help-content'));
},
'submit @ui.search': function (e) {
e.preventDefault();
let query = this.ui.query.val();
this.fetch(['owner', 'items', 'clients'], query)
.then(response => this.showData(response))
.catch(err => {
this.showError(err);
});
}
},
@ -88,18 +40,39 @@ module.exports = Mn.View.extend({
onRender: function () {
let view = this;
view.fetch(['owner', 'items', 'clients'])
App.Api.Nginx.AccessLists.getAll(['owner', 'items', 'clients'])
.then(response => {
if (!view.isDestroyed()) {
if (response && response.length) {
view.showData(response);
view.showChildView('list_region', new ListView({
collection: new AccessListModel.Collection(response)
}));
} else {
view.showEmpty();
let manage = App.Cache.User.canManage('access_lists');
view.showChildView('list_region', new EmptyView({
title: App.i18n('access-lists', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('access-lists', 'add') : null,
btn_color: 'teal',
permission: 'access_lists',
action: function () {
App.Controller.showNginxAccessListForm();
}
}));
}
}
})
.catch(err => {
view.showError(err);
view.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showNginxAccess();
}
}));
console.error(err);
})
.then(() => {
view.ui.dimmer.removeClass('active');

View File

@ -18,14 +18,6 @@
<input type="text" name="domain_names" class="form-control" id="input-domains" value="<%- domain_names.join(',') %>" required>
<div class="text-blue"><i class="fe fe-alert-triangle"></i> <%- i18n('ssl', 'hosts-warning') %></div>
</div>
<div class="mb-3 test-domains-container">
<button type="button" class="btn btn-secondary test-domains col-sm-12"><%- i18n('certificates', 'test-reachability') %></button>
<div class="text-secondary small">
<i class="fe fe-info"></i>
<%- i18n('certificates', 'reachability-info') %>
</div>
</div>
</div>
<div class="col-sm-12 col-md-12">
<div class="form-group">

View File

@ -29,8 +29,6 @@ module.exports = Mn.View.extend({
non_loader_content: '.non-loader-content',
le_error_info: '#le-error-info',
domain_names: 'input[name="domain_names"]',
test_domains_container: '.test-domains-container',
test_domains_button: '.test-domains',
buttons: '.modal-footer button',
cancel: 'button.cancel',
save: 'button.save',
@ -58,12 +56,10 @@ module.exports = Mn.View.extend({
this.ui.dns_provider_credentials.prop('required', 'required');
}
this.ui.dns_challenge_content.show();
this.ui.test_domains_container.hide();
} else {
this.ui.dns_provider.prop('required', false);
this.ui.dns_provider_credentials.prop('required', false);
this.ui.dns_challenge_content.hide();
this.ui.test_domains_container.show();
}
},
@ -209,23 +205,6 @@ module.exports = Mn.View.extend({
this.ui.non_loader_content.show();
});
},
'click @ui.test_domains_button': function (e) {
e.preventDefault();
const domainNames = this.ui.domain_names[0].value.split(',');
if (domainNames && domainNames.length > 0) {
this.model.set('domain_names', domainNames);
this.model.set('back_to_add', true);
App.Controller.showNginxCertificateTestReachability(this.model);
}
},
'change @ui.domain_names': function(e){
const domainNames = e.target.value.split(',');
if (domainNames && domainNames.length > 0) {
this.ui.test_domains_button.prop('disabled', false);
} else {
this.ui.test_domains_button.prop('disabled', true);
}
},
'change @ui.other_certificate_key': function(e){
this.setFileName("other_certificate_key_label", e)
},
@ -278,12 +257,6 @@ module.exports = Mn.View.extend({
this.ui.credentials_file_content.hide();
this.ui.loader_content.hide();
this.ui.le_error_info.hide();
if (this.ui.domain_names[0]) {
const domainNames = this.ui.domain_names[0].value.split(',');
if (!domainNames || domainNames.length === 0 || (domainNames.length === 1 && domainNames[0] === "")) {
this.ui.test_domains_button.prop('disabled', true);
}
}
},
initialize: function (options) {

View File

@ -42,9 +42,6 @@
<% if (provider === 'letsencrypt') { %>
<a href="#" class="renew dropdown-item"><i class="dropdown-icon fe fe-refresh-cw"></i> <%- i18n('certificates', 'force-renew') %></a>
<a href="#" class="download dropdown-item"><i class="dropdown-icon fe fe-download"></i> <%- i18n('certificates', 'download') %></a>
<% if (meta.dns_challenge === false) { %>
<a href="#" class="test dropdown-item"><i class="dropdown-icon fe fe-globe"></i> <%- i18n('certificates', 'test-reachability') %></a>
<% } %>
<div class="dropdown-divider"></div>
<% } %>
<a href="#" class="delete dropdown-item"><i class="dropdown-icon fe fe-trash-2"></i> <%- i18n('str', 'delete') %></a>

View File

@ -2,7 +2,7 @@ const Mn = require('backbone.marionette');
const moment = require('moment');
const App = require('../../../main');
const template = require('./item.ejs');
const dns_providers = require('../../../../../../global/certbot-dns-plugins');
const dns_providers = require('../../../../../../global/certbot-dns-plugins')
module.exports = Mn.View.extend({
template: template,
@ -12,8 +12,7 @@ module.exports = Mn.View.extend({
host_link: '.host-link',
renew: 'a.renew',
delete: 'a.delete',
download: 'a.download',
test: 'a.test'
download: 'a.download'
},
events: {
@ -35,13 +34,8 @@ module.exports = Mn.View.extend({
'click @ui.download': function (e) {
e.preventDefault();
App.Api.Nginx.Certificates.download(this.model.get('id'));
},
'click @ui.test': function (e) {
e.preventDefault();
App.Controller.showNginxCertificateTestReachability(this.model);
},
App.Api.Nginx.Certificates.download(this.model.get('id'))
}
},
templateContext: {

View File

@ -3,14 +3,6 @@
<div class="card-header">
<h3 class="card-title"><%- i18n('certificates', 'title') %></h3>
<div class="card-options">
<form class="search-form" role="search">
<div class="input-icon">
<span class="input-icon-addon">
<i class="fe fe-search"></i>
</span>
<input name="source-query" type="text" value="" class="form-control form-control-sm" placeholder="<%- i18n('certificates', 'search') %>" aria-label="<%- i18n('certificates', 'search') %>">
</div>
</form>
<a href="#" class="btn btn-outline-secondary btn-sm ml-2 help"><i class="fe fe-help-circle"></i></a>
<% if (showAddButton) { %>
<div class="dropdown">

View File

@ -14,44 +14,7 @@ module.exports = Mn.View.extend({
list_region: '.list-region',
add: '.add-item',
help: '.help',
dimmer: '.dimmer',
search: '.search-form',
query: 'input[name="source-query"]'
},
fetch: App.Api.Nginx.Certificates.getAll,
showData: function(response) {
this.showChildView('list_region', new ListView({
collection: new CertificateModel.Collection(response)
}));
},
showError: function(err) {
this.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showNginxCertificates();
}
}));
console.error(err);
},
showEmpty: function() {
let manage = App.Cache.User.canManage('certificates');
this.showChildView('list_region', new EmptyView({
title: App.i18n('certificates', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('certificates', 'add') : null,
btn_color: 'pink',
permission: 'certificates',
action: function () {
App.Controller.showNginxCertificateForm();
}
}));
dimmer: '.dimmer'
},
regions: {
@ -68,17 +31,6 @@ module.exports = Mn.View.extend({
'click @ui.help': function (e) {
e.preventDefault();
App.Controller.showHelp(App.i18n('certificates', 'help-title'), App.i18n('certificates', 'help-content'));
},
'submit @ui.search': function (e) {
e.preventDefault();
let query = this.ui.query.val();
this.fetch(['owner'], query)
.then(response => this.showData(response))
.catch(err => {
this.showError(err);
});
}
},
@ -89,18 +41,39 @@ module.exports = Mn.View.extend({
onRender: function () {
let view = this;
view.fetch(['owner'])
App.Api.Nginx.Certificates.getAll(['owner'])
.then(response => {
if (!view.isDestroyed()) {
if (response && response.length) {
view.showData(response);
view.showChildView('list_region', new ListView({
collection: new CertificateModel.Collection(response)
}));
} else {
view.showEmpty();
let manage = App.Cache.User.canManage('certificates');
view.showChildView('list_region', new EmptyView({
title: App.i18n('certificates', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('certificates', 'add') : null,
btn_color: 'pink',
permission: 'certificates',
action: function () {
App.Controller.showNginxCertificateForm();
}
}));
}
}
})
.catch(err => {
view.showError(err);
view.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showNginxCertificates();
}
}));
console.error(err);
})
.then(() => {
view.ui.dimmer.removeClass('active');

View File

@ -1,15 +0,0 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><%- i18n('certificates', 'reachability-title') %></h5>
</div>
<div class="modal-body">
<div class="waiting text-center">
<%= i18n('str', 'please-wait') %>
</div>
<div class="alert alert-danger error" role="alert"></div>
<div class="alert alert-success success" role="alert"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary cancel" disabled><%- i18n('str', 'close') %></button>
</div>
</div>

View File

@ -1,75 +0,0 @@
const Mn = require('backbone.marionette');
const App = require('../../main');
const template = require('./test.ejs');
module.exports = Mn.View.extend({
template: template,
className: 'modal-dialog',
ui: {
waiting: '.waiting',
error: '.error',
success: '.success',
close: 'button.cancel'
},
events: {
'click @ui.close': function (e) {
e.preventDefault();
if (this.model.get('back_to_add')) {
App.Controller.showNginxCertificateForm(this.model);
} else {
App.UI.closeModal();
}
},
},
onRender: function () {
this.ui.error.hide();
this.ui.success.hide();
App.Api.Nginx.Certificates.testHttpChallenge(this.model.get('domain_names'))
.then((result) => {
let allOk = true;
let text = '';
for (const domain in result) {
const status = result[domain];
if (status === 'ok') {
text += `<p><strong>${domain}:</strong> ${App.i18n('certificates', 'reachability-ok')}</p>`;
} else {
allOk = false;
if (status === 'no-host') {
text += `<p><strong>${domain}:</strong> ${App.i18n('certificates', 'reachability-not-resolved')}</p>`;
} else if (status === 'failed') {
text += `<p><strong>${domain}:</strong> ${App.i18n('certificates', 'reachability-failed-to-check')}</p>`;
} else if (status === '404') {
text += `<p><strong>${domain}:</strong> ${App.i18n('certificates', 'reachability-404')}</p>`;
} else if (status === 'wrong-data') {
text += `<p><strong>${domain}:</strong> ${App.i18n('certificates', 'reachability-wrong-data')}</p>`;
} else if (status.startsWith('other:')) {
const code = status.substring(6);
text += `<p><strong>${domain}:</strong> ${App.i18n('certificates', 'reachability-other', {code})}</p>`;
} else {
// This should never happen
text += `<p><strong>${domain}:</strong> ?</p>`;
}
}
}
this.ui.waiting.hide();
if (allOk) {
this.ui.success.html(text).show();
} else {
this.ui.error.html(text).show();
}
this.ui.close.prop('disabled', false);
})
.catch((e) => {
console.error(e);
this.ui.waiting.hide();
this.ui.error.text(App.i18n('certificates', 'reachability-failed-to-reach-api')).show();
this.ui.close.prop('disabled', false);
});
}
});

View File

@ -7,7 +7,7 @@
<form>
<div class="row">
<div class="col-sm-12 col-md-12">
<%= i18n('dead-hosts', 'delete-confirm', {domains: domain_names.join(', ').toHtmlEntities()}) %>
<%= i18n('dead-hosts', 'delete-confirm', {domains: domain_names.join(', ')}) %>
<% if (certificate_id) { %>
<br><br>
<%- i18n('ssl', 'delete-ssl') %>

View File

@ -3,14 +3,6 @@
<div class="card-header">
<h3 class="card-title"><%- i18n('dead-hosts', 'title') %></h3>
<div class="card-options">
<form class="search-form" role="search">
<div class="input-icon">
<span class="input-icon-addon">
<i class="fe fe-search"></i>
</span>
<input name="source-query" type="text" value="" class="form-control form-control-sm" placeholder="<%- i18n('dead-hosts', 'search') %>" aria-label="<%- i18n('dead-hosts', 'search') %>">
</div>
</form>
<a href="#" class="btn btn-outline-secondary btn-sm ml-2 help"><i class="fe fe-help-circle"></i></a>
<% if (showAddButton) { %>
<a href="#" class="btn btn-outline-danger btn-sm ml-2 add-item"><%- i18n('dead-hosts', 'add') %></a>

View File

@ -14,44 +14,7 @@ module.exports = Mn.View.extend({
list_region: '.list-region',
add: '.add-item',
help: '.help',
dimmer: '.dimmer',
search: '.search-form',
query: 'input[name="source-query"]'
},
fetch: App.Api.Nginx.DeadHosts.getAll,
showData: function(response) {
this.showChildView('list_region', new ListView({
collection: new DeadHostModel.Collection(response)
}));
},
showError: function(err) {
this.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showNginxDead();
}
}));
console.error(err);
},
showEmpty: function() {
let manage = App.Cache.User.canManage('dead_hosts');
this.showChildView('list_region', new EmptyView({
title: App.i18n('dead-hosts', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('dead-hosts', 'add') : null,
btn_color: 'danger',
permission: 'dead_hosts',
action: function () {
App.Controller.showNginxDeadForm();
}
}));
dimmer: '.dimmer'
},
regions: {
@ -67,17 +30,6 @@ module.exports = Mn.View.extend({
'click @ui.help': function (e) {
e.preventDefault();
App.Controller.showHelp(App.i18n('dead-hosts', 'help-title'), App.i18n('dead-hosts', 'help-content'));
},
'submit @ui.search': function (e) {
e.preventDefault();
let query = this.ui.query.val();
this.fetch(['owner', 'certificate'], query)
.then(response => this.showData(response))
.catch(err => {
this.showError(err);
});
}
},
@ -88,18 +40,39 @@ module.exports = Mn.View.extend({
onRender: function () {
let view = this;
view.fetch(['owner', 'certificate'])
App.Api.Nginx.DeadHosts.getAll(['owner', 'certificate'])
.then(response => {
if (!view.isDestroyed()) {
if (response && response.length) {
view.showData(response);
view.showChildView('list_region', new ListView({
collection: new DeadHostModel.Collection(response)
}));
} else {
view.showEmpty();
let manage = App.Cache.User.canManage('dead_hosts');
view.showChildView('list_region', new EmptyView({
title: App.i18n('dead-hosts', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('dead-hosts', 'add') : null,
btn_color: 'danger',
permission: 'dead_hosts',
action: function () {
App.Controller.showNginxDeadForm();
}
}));
}
}
})
.catch(err => {
view.showError(err);
view.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showNginxDead();
}
}));
console.error(err);
})
.then(() => {
view.ui.dimmer.removeClass('active');

View File

@ -7,7 +7,7 @@
<form>
<div class="row">
<div class="col-sm-12 col-md-12">
<%= i18n('proxy-hosts', 'delete-confirm', {domains: domain_names.join(', ').toHtmlEntities()}) %>
<%= i18n('proxy-hosts', 'delete-confirm', {domains: domain_names.join(', ')}) %>
<% if (certificate_id) { %>
<br><br>
<%- i18n('ssl', 'delete-ssl') %>

View File

@ -3,14 +3,6 @@
<div class="card-header">
<h3 class="card-title"><%- i18n('proxy-hosts', 'title') %></h3>
<div class="card-options">
<form class="search-form" role="search">
<div class="input-icon">
<span class="input-icon-addon">
<i class="fe fe-search"></i>
</span>
<input name="source-query" type="text" value="" class="form-control form-control-sm" placeholder="<%- i18n('proxy-hosts', 'search') %>" aria-label="<%- i18n('proxy-hosts', 'search') %>">
</div>
</form>
<a href="#" class="btn btn-outline-secondary btn-sm ml-2 help"><i class="fe fe-help-circle"></i></a>
<% if (showAddButton) { %>
<a href="#" class="btn btn-outline-success btn-sm ml-2 add-item"><%- i18n('proxy-hosts', 'add') %></a>

View File

@ -14,44 +14,7 @@ module.exports = Mn.View.extend({
list_region: '.list-region',
add: '.add-item',
help: '.help',
dimmer: '.dimmer',
search: '.search-form',
query: 'input[name="source-query"]'
},
fetch: App.Api.Nginx.ProxyHosts.getAll,
showData: function(response) {
this.showChildView('list_region', new ListView({
collection: new ProxyHostModel.Collection(response)
}));
},
showError: function(err) {
this.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showNginxProxy();
}
}));
console.error(err);
},
showEmpty: function() {
let manage = App.Cache.User.canManage('proxy_hosts');
this.showChildView('list_region', new EmptyView({
title: App.i18n('proxy-hosts', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('proxy-hosts', 'add') : null,
btn_color: 'success',
permission: 'proxy_hosts',
action: function () {
App.Controller.showNginxProxyForm();
}
}));
dimmer: '.dimmer'
},
regions: {
@ -67,17 +30,6 @@ module.exports = Mn.View.extend({
'click @ui.help': function (e) {
e.preventDefault();
App.Controller.showHelp(App.i18n('proxy-hosts', 'help-title'), App.i18n('proxy-hosts', 'help-content'));
},
'submit @ui.search': function (e) {
e.preventDefault();
let query = this.ui.query.val();
this.fetch(['owner', 'access_list', 'certificate'], query)
.then(response => this.showData(response))
.catch(err => {
this.showError(err);
});
}
},
@ -88,18 +40,39 @@ module.exports = Mn.View.extend({
onRender: function () {
let view = this;
view.fetch(['owner', 'access_list', 'certificate'])
App.Api.Nginx.ProxyHosts.getAll(['owner', 'access_list', 'certificate'])
.then(response => {
if (!view.isDestroyed()) {
if (response && response.length) {
view.showData(response);
view.showChildView('list_region', new ListView({
collection: new ProxyHostModel.Collection(response)
}));
} else {
view.showEmpty();
let manage = App.Cache.User.canManage('proxy_hosts');
view.showChildView('list_region', new EmptyView({
title: App.i18n('proxy-hosts', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('proxy-hosts', 'add') : null,
btn_color: 'success',
permission: 'proxy_hosts',
action: function () {
App.Controller.showNginxProxyForm();
}
}));
}
}
})
.catch(err => {
view.showError(err);
view.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showNginxProxy();
}
}));
console.error(err);
})
.then(() => {
view.ui.dimmer.removeClass('active');

View File

@ -7,7 +7,7 @@
<form>
<div class="row">
<div class="col-sm-12 col-md-12">
<%= i18n('redirection-hosts', 'delete-confirm', {domains: domain_names.join(', ').toHtmlEntities()}) %>
<%= i18n('redirection-hosts', 'delete-confirm', {domains: domain_names.join(', ')}) %>
<% if (certificate_id) { %>
<br><br>
<%- i18n('ssl', 'delete-ssl') %>

View File

@ -1,19 +1,11 @@
<div class="card">
<div class="card-status bg-yellow"></div>
<div class="card-header">
<h3 class="card-title"><%- i18n('redirection-hosts', 'title') %></h3>
<h3 class="card-title">Redirection Hosts</h3>
<div class="card-options">
<form class="search-form" role="search">
<div class="input-icon">
<span class="input-icon-addon">
<i class="fe fe-search"></i>
</span>
<input name="source-query" type="text" value="" class="form-control form-control-sm" placeholder="<%- i18n('redirection-hosts', 'search') %>" aria-label="<%- i18n('redirection-hosts', 'search') %>">
</div>
</form>
<a href="#" class="btn btn-outline-secondary btn-sm ml-2 help"><i class="fe fe-help-circle"></i></a>
<% if (showAddButton) { %>
<a href="#" class="btn btn-outline-yellow btn-sm ml-2 add-item"><%- i18n('redirection-hosts', 'add') %></a>
<a href="#" class="btn btn-outline-yellow btn-sm ml-2 add-item">Add Redirection Host</a>
<% } %>
</div>
</div>

View File

@ -14,43 +14,7 @@ module.exports = Mn.View.extend({
list_region: '.list-region',
add: '.add-item',
help: '.help',
dimmer: '.dimmer',
search: '.search-form',
query: 'input[name="source-query"]'
},
fetch: App.Api.Nginx.RedirectionHosts.getAll,
showData: function(response) {
this.showChildView('list_region', new ListView({
collection: new RedirectionHostModel.Collection(response)
}));
},
showError: function(err) {
this.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showNginxRedirection();
}
}));
console.error(err);
},
showEmpty: function() {
let manage = App.Cache.User.canManage('redirection_hosts');
this.showChildView('list_region', new EmptyView({
title: App.i18n('redirection-hosts', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('redirection-hosts', 'add') : null,
btn_color: 'yellow',
permission: 'redirection_hosts',
action: function () {
App.Controller.showNginxRedirectionForm();
}
}));
dimmer: '.dimmer'
},
regions: {
@ -66,17 +30,6 @@ module.exports = Mn.View.extend({
'click @ui.help': function (e) {
e.preventDefault();
App.Controller.showHelp(App.i18n('redirection-hosts', 'help-title'), App.i18n('redirection-hosts', 'help-content'));
},
'submit @ui.search': function (e) {
e.preventDefault();
let query = this.ui.query.val();
this.fetch(['owner', 'certificate'], query)
.then(response => this.showData(response))
.catch(err => {
this.showError(err);
});
}
},
@ -87,18 +40,39 @@ module.exports = Mn.View.extend({
onRender: function () {
let view = this;
view.fetch(['owner', 'certificate'])
App.Api.Nginx.RedirectionHosts.getAll(['owner', 'certificate'])
.then(response => {
if (!view.isDestroyed()) {
if (response && response.length) {
view.showData(response);
view.showChildView('list_region', new ListView({
collection: new RedirectionHostModel.Collection(response)
}));
} else {
view.showEmpty();
let manage = App.Cache.User.canManage('redirection_hosts');
view.showChildView('list_region', new EmptyView({
title: App.i18n('redirection-hosts', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('redirection-hosts', 'add') : null,
btn_color: 'yellow',
permission: 'redirection_hosts',
action: function () {
App.Controller.showNginxRedirectionForm();
}
}));
}
}
})
.catch(err => {
view.showError(err);
view.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showNginxRedirection();
}
}));
console.error(err);
})
.then(() => {
view.ui.dimmer.removeClass('active');

View File

@ -3,14 +3,6 @@
<div class="card-header">
<h3 class="card-title"><%- i18n('streams', 'title') %></h3>
<div class="card-options">
<form class="search-form" role="search">
<div class="input-icon">
<span class="input-icon-addon">
<i class="fe fe-search"></i>
</span>
<input name="source-query" type="text" value="" class="form-control form-control-sm" placeholder="<%- i18n('streams', 'search') %>" aria-label="<%- i18n('streams', 'search') %>">
</div>
</form>
<a href="#" class="btn btn-outline-secondary btn-sm ml-2 help"><i class="fe fe-help-circle"></i></a>
<% if (showAddButton) { %>
<a href="#" class="btn btn-outline-blue btn-sm ml-2 add-item"><%- i18n('streams', 'add') %></a>

View File

@ -14,44 +14,7 @@ module.exports = Mn.View.extend({
list_region: '.list-region',
add: '.add-item',
help: '.help',
dimmer: '.dimmer',
search: '.search-form',
query: 'input[name="source-query"]'
},
fetch: App.Api.Nginx.Streams.getAll,
showData: function(response) {
this.showChildView('list_region', new ListView({
collection: new StreamModel.Collection(response)
}));
},
showError: function(err) {
this.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showNginxStream();
}
}));
console.error(err);
},
showEmpty: function() {
let manage = App.Cache.User.canManage('streams');
this.showChildView('list_region', new EmptyView({
title: App.i18n('streams', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('streams', 'add') : null,
btn_color: 'blue',
permission: 'streams',
action: function () {
App.Controller.showNginxStreamForm();
}
}));
dimmer: '.dimmer'
},
regions: {
@ -67,17 +30,6 @@ module.exports = Mn.View.extend({
'click @ui.help': function (e) {
e.preventDefault();
App.Controller.showHelp(App.i18n('streams', 'help-title'), App.i18n('streams', 'help-content'));
},
'submit @ui.search': function (e) {
e.preventDefault();
let query = this.ui.query.val();
this.fetch(['owner'], query)
.then(response => this.showData(response))
.catch(err => {
this.showError(err);
});
}
},
@ -88,18 +40,39 @@ module.exports = Mn.View.extend({
onRender: function () {
let view = this;
view.fetch(['owner'])
App.Api.Nginx.Streams.getAll(['owner'])
.then(response => {
if (!view.isDestroyed()) {
if (response && response.length) {
view.showData(response);
view.showChildView('list_region', new ListView({
collection: new StreamModel.Collection(response)
}));
} else {
view.showEmpty();
let manage = App.Cache.User.canManage('streams');
view.showChildView('list_region', new EmptyView({
title: App.i18n('streams', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('streams', 'add') : null,
btn_color: 'blue',
permission: 'streams',
action: function () {
App.Controller.showNginxStreamForm();
}
}));
}
}
})
.catch(err => {
view.showError(err);
view.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showNginxStream();
}
}));
console.error(err);
})
.then(() => {
view.ui.dimmer.removeClass('active');

View File

@ -3,7 +3,7 @@
<div class="row align-items-center">
<div class="col-auto">
<ul class="list-inline list-inline-dots mb-0">
<li class="list-inline-item"><a href="https://github.com/jc21/nginx-proxy-manager?utm_source=nginx-proxy-manager" target="_blank"><%- i18n('footer', 'fork-me') %></a></li>
<li class="list-inline-item"><a href="https://github.com/jc21/nginx-proxy-manager?utm_source=nginx-proxy-manager"><%- i18n('footer', 'fork-me') %></a></li>
</ul>
</div>
</div>

View File

@ -7,7 +7,7 @@
<form>
<div class="row">
<div class="col-sm-12 col-md-12">
<%= i18n('users', 'delete-confirm', {name: name.toHtmlEntities()}) %>
<%= i18n('users', 'delete-confirm', {name: name}) %>
</div>
</div>
</form>

View File

@ -3,14 +3,6 @@
<div class="card-header">
<h3 class="card-title"><%- i18n('users', 'title') %></h3>
<div class="card-options">
<form class="search-form" role="search">
<div class="input-icon">
<span class="input-icon-addon">
<i class="fe fe-search"></i>
</span>
<input name="source-query" type="text" value="" class="form-control form-control-sm" placeholder="<%- i18n('users', 'search') %>" aria-label="<%- i18n('users', 'search') %>">
</div>
</form>
<a href="#" class="btn btn-outline-teal btn-sm ml-2 add-item"><%- i18n('users', 'add') %></a>
</div>
</div>

View File

@ -12,29 +12,7 @@ module.exports = Mn.View.extend({
ui: {
list_region: '.list-region',
add: '.add-item',
dimmer: '.dimmer',
search: '.search-form',
query: 'input[name="source-query"]'
},
fetch: App.Api.Users.getAll,
showData: function(response) {
this.showChildView('list_region', new ListView({
collection: new UserModel.Collection(response)
}));
},
showError: function(err) {
this.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showUsers();
}
}));
console.error(err);
dimmer: '.dimmer'
},
regions: {
@ -45,31 +23,30 @@ module.exports = Mn.View.extend({
'click @ui.add': function (e) {
e.preventDefault();
App.Controller.showUserForm(new UserModel.Model());
},
'submit @ui.search': function (e) {
e.preventDefault();
let query = this.ui.query.val();
this.fetch(['permissions'], query)
.then(response => this.showData(response))
.catch(err => {
this.showError(err);
});
}
},
onRender: function () {
let view = this;
view.fetch(['permissions'])
App.Api.Users.getAll(['permissions'])
.then(response => {
if (!view.isDestroyed() && response && response.length) {
view.showData(response);
view.showChildView('list_region', new ListView({
collection: new UserModel.Collection(response)
}));
}
})
.catch(err => {
view.showError(err);
view.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showUsers();
}
}));
console.error(err);
})
.then(() => {
view.ui.dimmer.removeClass('active');

View File

@ -60,7 +60,7 @@
},
"footer": {
"fork-me": "Fork me on Github",
"copy": "&copy; 2022 <a href=\"{url}\" target=\"_blank\">jc21.com</a>.",
"copy": "&copy; 2021 <a href=\"{url}\" target=\"_blank\">jc21.com</a>.",
"theme": "Theme by <a href=\"{url}\" target=\"_blank\">Tabler</a>"
},
"dashboard": {
@ -132,8 +132,7 @@
"access-list": "Access List",
"allow-websocket-upgrade": "Websockets Support",
"ignore-invalid-upstream-ssl": "Ignore Invalid SSL",
"custom-forward-host-help": "Add a path for sub-folder forwarding.\nExample: 203.0.113.25/path/",
"search": "Search Host…"
"custom-forward-host-help": "Add a path for sub-folder forwarding.\nExample: 203.0.113.25/path"
},
"redirection-hosts": {
"title": "Redirection Hosts",
@ -147,8 +146,7 @@
"delete": "Delete Redirection Host",
"delete-confirm": "Are you sure you want to delete the Redirection host for: <strong>{domains}</strong>?",
"help-title": "What is a Redirection Host?",
"help-content": "A Redirection Host will redirect requests from the incoming domain and push the viewer to another domain.\nThe most common reason to use this type of host is when your website changes domains but you still have search engine or referrer links pointing to the old domain.",
"search": "Search Host…"
"help-content": "A Redirection Host will redirect requests from the incoming domain and push the viewer to another domain.\nThe most common reason to use this type of host is when your website changes domains but you still have search engine or referrer links pointing to the old domain."
},
"dead-hosts": {
"title": "404 Hosts",
@ -158,8 +156,7 @@
"delete": "Delete 404 Host",
"delete-confirm": "Are you sure you want to delete this 404 Host?",
"help-title": "What is a 404 Host?",
"help-content": "A 404 Host is simply a host setup that shows a 404 page.\nThis can be useful when your domain is listed in search engines and you want to provide a nicer error page or specifically to tell the search indexers that the domain pages no longer exist.\nAnother benefit of having this host is to track the logs for hits to it and view the referrers.",
"search": "Search Host…"
"help-content": "A 404 Host is simply a host setup that shows a 404 page.\nThis can be useful when your domain is listed in search engines and you want to provide a nicer error page or specifically to tell the search indexers that the domain pages no longer exist.\nAnother benefit of having this host is to track the logs for hits to it and view the referrers."
},
"streams": {
"title": "Streams",
@ -178,8 +175,7 @@
"delete": "Delete Stream",
"delete-confirm": "Are you sure you want to delete this Stream?",
"help-title": "What is a Stream?",
"help-content": "A relatively new feature for Nginx, a Stream will serve to forward TCP/UDP traffic directly to another computer on the network.\nIf you're running game servers, FTP or SSH servers this can come in handy.",
"search": "Search Incoming Port…"
"help-content": "A relatively new feature for Nginx, a Stream will serve to forward TCP/UDP traffic directly to another computer on the network.\nIf you're running game servers, FTP or SSH servers this can come in handy."
},
"certificates": {
"title": "SSL Certificates",
@ -194,19 +190,8 @@
"other-certificate-key": "Certificate Key",
"other-intermediate-certificate": "Intermediate Certificate",
"force-renew": "Renew Now",
"test-reachability": "Test Server Reachability",
"reachability-title": "Test Server Reachability",
"reachability-info": "Test whether the domains are reachable from the public internet using Site24x7. This is not necessary when using the DNS Challenge.",
"reachability-failed-to-reach-api": "Communication with the API failed, is NPM running correctly?",
"reachability-failed-to-check": "Failed to check the reachability due to a communication error with site24x7.com.",
"reachability-ok": "Your server is reachable and creating certificates should be possible.",
"reachability-404": "There is a server found at this domain but it does not seem to be Nginx Proxy Manager. Please make sure your domain points to the IP where your NPM instance is running.",
"reachability-not-resolved": "There is no server available at this domain. Please make sure your domain exists and points to the IP where your NPM instance is running and if necessary port 80 is forwarded in your router.",
"reachability-wrong-data": "There is a server found at this domain but it returned an unexpected data. Is it the NPM server? Please make sure your domain points to the IP where your NPM instance is running.",
"reachability-other": "There is a server found at this domain but it returned an unexpected status code {code}. Is it the NPM server? Please make sure your domain points to the IP where your NPM instance is running.",
"download": "Download",
"renew-title": "Renew Let's Encrypt Certificate",
"search": "Search Certificate…"
"renew-title": "Renew Let'sEncrypt Certificate"
},
"access-lists": {
"title": "Access Lists",
@ -230,8 +215,7 @@
"satisfy-any": "Satisfy Any",
"pass-auth": "Pass Auth to Host",
"access-add": "Add",
"auth-add": "Add",
"search": "Search Access…"
"auth-add": "Add"
},
"users": {
"title": "Users",
@ -257,8 +241,7 @@
"perms-visibility-all": "All Items",
"perm-manage": "Manage",
"perm-view": "View Only",
"perm-hidden": "Hidden",
"search": "Search User…"
"perm-hidden": "Hidden"
},
"audit-log": {
"title": "Audit Log",
@ -279,8 +262,7 @@
"renewed": "Renewed {name}",
"meta-title": "Details for Event",
"view-meta": "View Details",
"date": "Date",
"search": "Search Log…"
"date": "Date"
},
"settings": {
"title": "Settings",

View File

@ -103,13 +103,6 @@ window.tabler = {
}
};
String.prototype.toHtmlEntities = function() {
return this.replace(/./gm, function(s) {
// return "&#" + s.charCodeAt(0) + ";";
return (s.match(/[a-z0-9\s]+/i)) ? s : "&#" + s.charCodeAt(0) + ";";
});
};
require('tabler-core');
const App = require('./app/main');

View File

@ -17,7 +17,7 @@
<div class="card-title"><%- i18n('login', 'title') %></div>
<div class="form-group">
<label class="form-label"><%- i18n('str', 'email-address') %></label>
<input name="identity" type="email" class="form-control" placeholder="<%- i18n('str', 'email-address') %>" required autofocus>
<input name="identity" type="email" class="form-control" placeholder="<%- i18n('str', 'email-address') %>" required>
</div>
<div class="form-group">
<label class="form-label"><%- i18n('str', 'password') %></label>

View File

@ -26,7 +26,7 @@
"messageformat": "^2.3.0",
"messageformat-loader": "^0.8.1",
"mini-css-extract-plugin": "^0.9.0",
"moment": "^2.29.4",
"moment": "^2.24.0",
"node-sass": "^6.0.1",
"nodemon": "^2.0.2",
"numeral": "^2.0.6",

View File

@ -1501,9 +1501,9 @@ browserslist@^3.2.6:
electron-to-chromium "^1.3.47"
buffer-from@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
version "1.1.1"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
buffer-xor@^1.0.3:
version "1.0.3"
@ -4433,10 +4433,10 @@ mkdirp@^1.0.3:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
moment@^2.29.4:
version "2.29.4"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
moment@^2.24.0:
version "2.27.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d"
integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==
move-concurrently@^1.0.1:
version "1.0.1"
@ -5863,9 +5863,9 @@ source-map-support@^0.4.15:
source-map "^0.5.6"
source-map-support@~0.5.12:
version "0.5.21"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
version "0.5.19"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
dependencies:
buffer-from "^1.0.0"
source-map "^0.6.0"
@ -6214,9 +6214,9 @@ terser-webpack-plugin@^1.4.3:
worker-farm "^1.7.0"
terser@^4.1.2, terser@^4.6.3:
version "4.8.1"
resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.1.tgz#a00e5634562de2239fd404c649051bf6fc21144f"
integrity sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==
version "4.8.0"
resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17"
integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==
dependencies:
commander "^2.20.0"
source-map "~0.6.1"

View File

@ -69,7 +69,7 @@ dns_azure_zone2 = example.org:/subscriptions/99800903-fb14-4992-9aff-12eaf274462
cloudflare: {
display_name: 'Cloudflare',
package_name: 'certbot-dns-cloudflare',
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
// version_requirement: '', // Official plugin, no version requirement
dependencies: 'cloudflare',
credentials: `# Cloudflare API token
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567`,
@ -95,24 +95,13 @@ dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567`,
cloudxns: {
display_name: 'CloudXNS',
package_name: 'certbot-dns-cloudxns',
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
// version_requirement: '', // Official plugin, no version requirement
dependencies: '',
credentials: `dns_cloudxns_api_key = 1234567890abcdef1234567890abcdef
dns_cloudxns_secret_key = 1122334455667788`,
full_plugin_name: 'dns-cloudxns',
},
//####################################################//
constellix: {
display_name: 'Constellix',
package_name: 'certbot-dns-constellix',
version_requirement: '~=0.2.1',
dependencies: '',
credentials: `dns_constellix_apikey = 5fb4e76f-ac91-43e5-f982458bc595
dns_constellix_secretkey = 47d99fd0-32e7-4e07-85b46d08e70b
dns_constellix_endpoint = https://api.dns.constellix.com/v1`,
full_plugin_name: 'dns-constellix',
},
//####################################################//
corenetworks: {
display_name: 'Core Networks',
package_name: 'certbot-dns-corenetworks',
@ -147,7 +136,7 @@ dns_desec_endpoint = https://desec.io/api/v1/`,
duckdns: {
display_name: 'DuckDNS',
package_name: 'certbot-dns-duckdns',
version_requirement: '~=0.9',
version_requirement: '~=0.6',
dependencies: '',
credentials: 'dns_duckdns_token=your-duckdns-token',
full_plugin_name: 'dns-duckdns',
@ -156,7 +145,7 @@ dns_desec_endpoint = https://desec.io/api/v1/`,
digitalocean: {
display_name: 'DigitalOcean',
package_name: 'certbot-dns-digitalocean',
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
// version_requirement: '', // Official plugin, no version requirement
dependencies: '',
credentials: 'dns_digitalocean_token = 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff',
full_plugin_name: 'dns-digitalocean',
@ -176,7 +165,7 @@ directadmin_password = aSuperStrongPassword`,
dnsimple: {
display_name: 'DNSimple',
package_name: 'certbot-dns-dnsimple',
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
// version_requirement: '', // Official plugin, no version requirement
dependencies: '',
credentials: 'dns_dnsimple_token = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw',
full_plugin_name: 'dns-dnsimple',
@ -185,7 +174,7 @@ directadmin_password = aSuperStrongPassword`,
dnsmadeeasy: {
display_name: 'DNS Made Easy',
package_name: 'certbot-dns-dnsmadeeasy',
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
// version_requirement: '', // Official plugin, no version requirement
dependencies: '',
credentials: `dns_dnsmadeeasy_api_key = 1c1a3c91-4770-4ce7-96f4-54c0eb0e457a
dns_dnsmadeeasy_secret_key = c9b5625f-9834-4ff8-baba-4ed5f32cae55`,
@ -197,30 +186,11 @@ dns_dnsmadeeasy_secret_key = c9b5625f-9834-4ff8-baba-4ed5f32cae55`,
package_name: 'certbot-dns-dnspod',
version_requirement: '~=0.1.0',
dependencies: '',
credentials: `dns_dnspod_email = "email@example.com"
dns_dnspod_api_token = "id,key"`,
credentials: `dns_dnspod_email = "DNSPOD-API-REQUIRES-A-VALID-EMAIL"
dns_dnspod_api_token = "DNSPOD-API-TOKEN"`,
full_plugin_name: 'dns-dnspod',
},
//####################################################//
domainoffensive: {
display_name: 'DomainOffensive (do.de)',
package_name: 'certbot-dns-do',
version_requirement: '~=0.31.0',
dependencies: '',
credentials: 'dns_do_api_token = YOUR_DO_DE_AUTH_TOKEN',
full_plugin_name: 'dns-do',
},
//####################################################//
domeneshop: {
display_name: 'Domeneshop',
package_name: 'certbot-dns-domeneshop',
version_requirement: '~=0.2.8',
dependencies: '',
credentials: `dns_domeneshop_client_token=YOUR_DOMENESHOP_CLIENT_TOKEN
dns_domeneshop_client_secret=YOUR_DOMENESHOP_CLIENT_SECRET`,
full_plugin_name: 'dns-domeneshop',
},
//####################################################//
dynu: {
display_name: 'Dynu',
package_name: 'certbot-dns-dynu',
@ -267,7 +237,7 @@ dns_godaddy_key = abcdef0123456789abcdef01234567abcdef0123`,
google: {
display_name: 'Google',
package_name: 'certbot-dns-google',
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
// version_requirement: '', // Official plugin, no version requirement
dependencies: '',
credentials: `{
"type": "service_account",
@ -351,7 +321,7 @@ dns_joker_domain = <Dynamic DNS Domain>`,
linode: {
display_name: 'Linode',
package_name: 'certbot-dns-linode',
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
// version_requirement: '', // Official plugin, no version requirement
dependencies: '',
credentials: `dns_linode_key = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ64
dns_linode_version = [<blank>|3|4]`,
@ -371,23 +341,13 @@ dns_loopia_password = abcdef0123456789abcdef01234567abcdef0123`,
luadns: {
display_name: 'LuaDNS',
package_name: 'certbot-dns-luadns',
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
// version_requirement: '', // Official plugin, no version requirement
dependencies: '',
credentials: `dns_luadns_email = user@example.com
dns_luadns_token = 0123456789abcdef0123456789abcdef`,
full_plugin_name: 'dns-luadns',
},
//####################################################//
namecheap: {
display_name: 'Namecheap',
package_name: 'certbot-dns-namecheap',
version_requirement: '~=1.0.0',
dependencies: '',
credentials: `dns_namecheap_username = 123456
dns_namecheap_api_key = 0123456789abcdef0123456789abcdef01234567`,
full_plugin_name: 'dns-namecheap',
},
//####################################################//
netcup: {
display_name: 'netcup',
package_name: 'certbot-dns-netcup',
@ -411,7 +371,7 @@ dns_netcup_api_password = abcdef0123456789abcdef01234567abcdef0123`,
nsone: {
display_name: 'NS1',
package_name: 'certbot-dns-nsone',
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
// version_requirement: '', // Official plugin, no version requirement
dependencies: '',
credentials: 'dns_nsone_api_key = MDAwMDAwMDAwMDAwMDAw',
full_plugin_name: 'dns-nsone',
@ -434,7 +394,7 @@ key_file = ~/.oci/oci_api_key.pem`,
ovh: {
display_name: 'OVH',
package_name: 'certbot-dns-ovh',
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
// version_requirement: '', // Official plugin, no version requirement
dependencies: '',
credentials: `dns_ovh_endpoint = ovh-eu
dns_ovh_application_key = MDAwMDAwMDAwMDAw
@ -476,7 +436,7 @@ certbot_regru:dns_password=password`,
rfc2136: {
display_name: 'RFC 2136',
package_name: 'certbot-dns-rfc2136',
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
// version_requirement: '', // Official plugin, no version requirement
dependencies: '',
credentials: `# Target DNS server
dns_rfc2136_server = 192.0.2.1
@ -494,7 +454,7 @@ dns_rfc2136_algorithm = HMAC-SHA512`,
route53: {
display_name: 'Route 53 (Amazon)',
package_name: 'certbot-dns-route53',
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
// version_requirement: '', // Official plugin, no version requirement
dependencies: '',
credentials: `[default]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
@ -505,23 +465,13 @@ aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY`,
transip: {
display_name: 'TransIP',
package_name: 'certbot-dns-transip',
version_requirement: '~=0.4.3',
version_requirement: '~=0.3.3',
dependencies: '',
credentials: `dns_transip_username = my_username
dns_transip_key_file = /etc/letsencrypt/transip-rsa.key`,
full_plugin_name: 'dns-transip',
},
//####################################################//
tencentcloud: {
display_name: 'Tencent Cloud',
package_name: 'certbot-dns-tencentcloud',
version_requirement: '~=2.0.0',
dependencies: '',
credentials: `dns_tencentcloud_secret_id = TENCENT_CLOUD_SECRET_ID
dns_tencentcloud_secret_key = TENCENT_CLOUD_SECRET_KEY`,
full_plugin_name: 'dns-tencentcloud',
},
//####################################################//
vultr: {
display_name: 'Vultr',
package_name: 'certbot-dns-vultr',

View File

@ -12,7 +12,7 @@ ALL_FILES=$(find . -follow)
for FILE in $ALL_FILES
do
# remove preceding ./
# remove preceeding ./
FILE=$(echo "$FILE" | sed -E "s/\.\///g")
echo '======================================='
echo "FILE: $FILE"

View File

@ -3,7 +3,7 @@
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
. "$DIR/.common.sh"
DOCKER_IMAGE=nginxproxymanager/nginx-full:certbot-node
DOCKER_IMAGE=jc21/nginx-full:node
# Ensure docker exists
if hash docker 2>/dev/null; then

View File

@ -253,9 +253,9 @@ astral-regex@^1.0.0:
integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
async@^3.2.0:
version "3.2.4"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c"
integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==
version "3.2.0"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720"
integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==
asynckit@^0.4.0:
version "0.4.0"
@ -1809,9 +1809,9 @@ mocha@^8.1.1:
yargs-unparser "1.6.1"
moment@^2.27.0:
version "2.29.4"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
version "2.27.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d"
integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==
ms@2.0.0:
version "2.0.0"