Compare commits

..

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

150 changed files with 2374 additions and 3979 deletions

View File

@ -6,30 +6,15 @@ labels: bug
assignees: '' assignees: ''
--- ---
<!--
Are you in the right place?
- If you are looking for support on how to get your upstream server forwarding, please consider asking the community on Reddit.
- If you are writing code changes to contribute and need to ask about the internals of the software, Gitter is the best place to ask.
- If you think you found a bug with NPM (not Nginx, or your upstream server or MySql) then you are in the *right place.*
-->
**Checklist** **Checklist**
- Have you pulled and found the error with `jc21/nginx-proxy-manager:latest` docker image? - Have you pulled and found the error with `jc21/nginx-proxy-manager:latest` docker image?
- Yes / No
- Are you sure you're not using someone else's docker image? - Are you sure you're not using someone else's docker image?
- Yes / No - If having problems with Lets Encrypt, have you made absolutely sure your site is accessible from outside of your network?
- Have you searched for similar issues (both open and closed)?
- Yes / No
**Describe the bug** **Describe the bug**
<!-- A clear and concise description of what the bug is. --> - A clear and concise description of what the bug is.
- What version of Nginx Proxy Manager is reported on the login page?
**Nginx Proxy Manager Version**
<!-- What version of Nginx Proxy Manager is reported on the login page? -->
**To Reproduce** **To Reproduce**
Steps to reproduce the behavior: Steps to reproduce the behavior:
@ -38,18 +23,14 @@ Steps to reproduce the behavior:
3. Scroll down to '....' 3. Scroll down to '....'
4. See error 4. See error
**Expected behavior** **Expected behavior**
<!-- A clear and concise description of what you expected to happen. --> A clear and concise description of what you expected to happen.
**Screenshots** **Screenshots**
<!-- If applicable, add screenshots to help explain your problem. --> If applicable, add screenshots to help explain your problem.
**Operating System** **Operating System**
<!-- Please specify if using a Rpi, Mac, orchestration tool or any other setups that might affect the reproduction of this error. --> - Please specify if using a Rpi, Mac, orchestration tool or any other setups that might affect the reproduction of this error.
**Additional context** **Additional context**
<!-- Add any other context about the problem here, docker version, browser version, logs if applicable to the problem. Too much info is better than too little. --> Add any other context about the problem here, docker version, browser version if applicable to the problem. Too much info is better than too little.

View File

@ -1,18 +0,0 @@
---
name: DNS challenge provider request
about: Suggest a new provider to be available for a certificate DNS challenge
title: ''
labels: dns provider request
assignees: ''
---
**What provider would you like to see added to NPM?**
<!-- What is this provider called? -->
**Have you checked if a certbot plugin exists?**
<!--
Currently NPM only supports DNS challenge providers for which a certbot plugin exists.
You can visit pypi.org, and search for a package with the name `certbot-dns-<privider>`.
-->

View File

@ -7,26 +7,14 @@ assignees: ''
--- ---
<!--
Are you in the right place?
- If you are looking for support on how to get your upstream server forwarding, please consider asking the community on Reddit.
- If you are writing code changes to contribute and need to ask about the internals of the software, Gitter is the best place to ask.
- If you think you found a bug with NPM (not Nginx, or your upstream server or MySql) then you are in the *right place.*
-->
**Is your feature request related to a problem? Please describe.** **Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] --> A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like** **Describe the solution you'd like**
<!-- A clear and concise description of what you want to happen. --> A clear and concise description of what you want to happen.
**Describe alternatives you've considered** **Describe alternatives you've considered**
<!-- A clear and concise description of any alternative solutions or features you've considered. --> A clear and concise description of any alternative solutions or features you've considered.
**Additional context** **Additional context**
<!-- Add any other context or screenshots about the feature request here. --> Add any other context or screenshots about the feature request here.

View File

@ -0,0 +1,16 @@
---
name: Product Support
about: Need help configuring the software?
title: ''
labels: product-support
assignees: ''
---
**Checklist**
- Please read the [setup instructions](https://nginxproxymanager.com/setup/)
- Please read the [FAQ](https://nginxproxymanager.com/faq/)
**What is troubling you?**
_Clear and concise description of what you're trying to do and what isn't working for you_

View File

@ -0,0 +1,10 @@
{
"database": {
"engine": "mysql",
"host": "db",
"name": "npm",
"user": "npm",
"password": "npm",
"port": 3306
}
}

View File

@ -0,0 +1,11 @@
{
"database": {
"engine": "knex-native",
"knex": {
"client": "sqlite3",
"connection": {
"filename": "/data/database.sqlite"
}
}
}
}

View File

@ -1 +1 @@
2.9.19 2.6.1

9
Jenkinsfile vendored
View File

@ -62,13 +62,12 @@ pipeline {
stage('Backend') { stage('Backend') {
steps { steps {
echo 'Checking Syntax ...' echo 'Checking Syntax ...'
sh 'docker pull nginxproxymanager/nginx-full:certbot-node'
// See: https://github.com/yarnpkg/yarn/issues/3254 // See: https://github.com/yarnpkg/yarn/issues/3254
sh '''docker run --rm \\ sh '''docker run --rm \\
-v "$(pwd)/backend:/app" \\ -v "$(pwd)/backend:/app" \\
-v "$(pwd)/global:/app/global" \\ -v "$(pwd)/global:/app/global" \\
-w /app \\ -w /app \\
nginxproxymanager/nginx-full:certbot-node \\ node:latest \\
sh -c "yarn install && yarn eslint . && rm -rf node_modules" sh -c "yarn install && yarn eslint . && rm -rf node_modules"
''' '''
@ -214,16 +213,16 @@ pipeline {
} }
steps { steps {
script { script {
def comment = pullRequest.comment("This is an automated message from CI:\n\nDocker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker/jc21/${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`\n\n**Note:** ensure you backup your NPM instance before testing this PR image! Especially if this PR contains database changes.") def comment = pullRequest.comment("Docker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker/jc21/${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`")
} }
} }
} }
} }
post { post {
always { 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 'echo Reverting ownership'
sh 'docker run --rm -v $(pwd):/data jc21/ci-tools chown -R $(id -u):$(id -g) /data' sh 'docker run --rm -v $(pwd):/data ${DOCKER_CI_TOOLS} chown -R $(id -u):$(id -g) /data'
} }
success { success {
juxtapose event: 'success' juxtapose event: 'success'

220
README.md
View File

@ -1,19 +1,25 @@
<p align="center"> <p align="center">
<img src="https://nginxproxymanager.com/github.png"> <img src="https://nginxproxymanager.com/github.png">
<br><br> <br><br>
<img src="https://img.shields.io/badge/version-2.9.19-green.svg?style=for-the-badge"> <img src="https://img.shields.io/badge/version-2.6.1-green.svg?style=for-the-badge">
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager"> <a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
<img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge"> <img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge">
</a> </a>
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager"> <a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
<img src="https://img.shields.io/docker/pulls/jc21/nginx-proxy-manager.svg?style=for-the-badge"> <img src="https://img.shields.io/docker/pulls/jc21/nginx-proxy-manager.svg?style=for-the-badge">
</a> </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>
</p> </p>
This project comes as a pre-built docker image that enables you to easily forward to your websites This project comes as a pre-built docker image that enables you to easily forward to your websites
running at home or otherwise, including free SSL, without having to know too much about Nginx or Letsencrypt. running at home or otherwise, including free SSL, without having to know too much about Nginx or Letsencrypt.
- [Quick Setup](#quick-setup) - [Quick Setup](https://nginxproxymanager.com#quick-setup)
- [Full Setup](https://nginxproxymanager.com/setup/) - [Full Setup](https://nginxproxymanager.com/setup/)
- [Screenshots](https://nginxproxymanager.com/screenshots/) - [Screenshots](https://nginxproxymanager.com/screenshots/)
@ -46,64 +52,160 @@ I won't go in to too much detail here but here are the basics for someone new to
3. Configure your domain name details to point to your home, either with a static ip or a service like DuckDNS or [Amazon Route53](https://github.com/jc21/route53-ddns) 3. Configure your domain name details to point to your home, either with a static ip or a service like DuckDNS or [Amazon Route53](https://github.com/jc21/route53-ddns)
4. Use the Nginx Proxy Manager as your gateway to forward to your other web based services 4. Use the Nginx Proxy Manager as your gateway to forward to your other web based services
## Quick Setup
1. Install Docker and Docker-Compose
- [Docker Install documentation](https://docs.docker.com/install/)
- [Docker-Compose Install documentation](https://docs.docker.com/compose/install/)
2. Create a docker-compose.yml file similar to this:
```yml
version: '3'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
```
3. Bring up your stack by running
```bash
docker-compose up -d
# If using docker-compose-plugin
docker compose up -d
```
4. Log in to the Admin UI
When your docker container is running, connect to it on port `81` for the admin interface.
Sometimes this can take a little bit because of the entropy of keys.
[http://127.0.0.1:81](http://127.0.0.1:81)
Default Admin User:
```
Email: admin@example.com
Password: changeme
```
Immediately after logging in with this default user you will be asked to modify your details and change your password.
## Contributors ## Contributors
Special thanks to [all of our contributors](https://github.com/NginxProxyManager/nginx-proxy-manager/graphs/contributors). Special thanks to the following contributors:
<!-- prettier-ignore-start -->
## Getting Support <!-- markdownlint-disable -->
<table>
1. [Found a bug?](https://github.com/NginxProxyManager/nginx-proxy-manager/issues) <tr>
2. [Discussions](https://github.com/NginxProxyManager/nginx-proxy-manager/discussions) <td align="center">
3. [Development Gitter](https://gitter.im/nginx-proxy-manager/community) <a href="https://github.com/Subv">
4. [Reddit](https://reddit.com/r/nginxproxymanager) <img src="https://avatars1.githubusercontent.com/u/357072?s=460&u=d8adcdc91d749ae53e177973ed9b6bb6c4c894a3&v=4" width="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" 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="80px;" alt=""/>
<br /><sub><b>Philip Mooney</b></sub>
</a>
</td>
</tr>
</table>
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->

View File

@ -40,12 +40,13 @@ app.use(function (req, res, next) {
} }
res.set({ res.set({
'X-XSS-Protection': '1; mode=block', 'Strict-Transport-Security': 'includeSubDomains; max-age=631138519; preload',
'X-Content-Type-Options': 'nosniff', 'X-XSS-Protection': '1; mode=block',
'X-Frame-Options': x_frame_options, 'X-Content-Type-Options': 'nosniff',
'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate', 'X-Frame-Options': x_frame_options,
Pragma: 'no-cache', 'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
Expires: 0 Pragma: 'no-cache',
Expires: 0
}); });
next(); next();
}); });
@ -74,7 +75,7 @@ app.use(function (err, req, res, next) {
// Not every error is worth logging - but this is good for now until it gets annoying. // Not every error is worth logging - but this is good for now until it gets annoying.
if (typeof err.stack !== 'undefined' && err.stack) { if (typeof err.stack !== 'undefined' && err.stack) {
if (process.env.NODE_ENV === 'development' || process.env.DEBUG) { if (process.env.NODE_ENV === 'development') {
log.debug(err.stack); log.debug(err.stack);
} else if (typeof err.public == 'undefined' || !err.public) { } else if (typeof err.public == 'undefined' || !err.public) {
log.warn(err.message); log.warn(err.message);

View File

@ -2,10 +2,7 @@
const logger = require('./logger').global; const logger = require('./logger').global;
async function appStart () { function appStart () {
// Create config file db settings if environment variables have been set
await createDbConfigFromEnvironment();
const migrate = require('./migrate'); const migrate = require('./migrate');
const setup = require('./setup'); const setup = require('./setup');
const app = require('./app'); const app = require('./app');
@ -42,94 +39,9 @@ async function appStart () {
}); });
} }
async function createDbConfigFromEnvironment() {
return new Promise((resolve, reject) => {
const envMysqlHost = process.env.DB_MYSQL_HOST || null;
const envMysqlPort = process.env.DB_MYSQL_PORT || null;
const envMysqlUser = process.env.DB_MYSQL_USER || null;
const envMysqlName = process.env.DB_MYSQL_NAME || null;
let envSqliteFile = process.env.DB_SQLITE_FILE || null;
const fs = require('fs');
const filename = (process.env.NODE_CONFIG_DIR || './config') + '/' + (process.env.NODE_ENV || 'default') + '.json';
let configData = {};
try {
configData = require(filename);
} catch (err) {
// do nothing
}
if (configData.database && configData.database.engine && !configData.database.fromEnv) {
logger.info('Manual db configuration already exists, skipping config creation from environment variables');
resolve();
return;
}
if ((!envMysqlHost || !envMysqlPort || !envMysqlUser || !envMysqlName) && !envSqliteFile){
envSqliteFile = '/data/database.sqlite';
logger.info(`No valid environment variables for database provided, using default SQLite file '${envSqliteFile}'`);
}
if (envMysqlHost && envMysqlPort && envMysqlUser && envMysqlName) {
const newConfig = {
fromEnv: true,
engine: 'mysql',
host: envMysqlHost,
port: envMysqlPort,
user: envMysqlUser,
password: process.env.DB_MYSQL_PASSWORD,
name: envMysqlName,
};
if (JSON.stringify(configData.database) === JSON.stringify(newConfig)) {
// Config is unchanged, skip overwrite
resolve();
return;
}
logger.info('Generating MySQL knex configuration from environment variables');
configData.database = newConfig;
} else {
const newConfig = {
fromEnv: true,
engine: 'knex-native',
knex: {
client: 'sqlite3',
connection: {
filename: envSqliteFile
},
useNullAsDefault: true
}
};
if (JSON.stringify(configData.database) === JSON.stringify(newConfig)) {
// Config is unchanged, skip overwrite
resolve();
return;
}
logger.info('Generating SQLite knex configuration');
configData.database = newConfig;
}
// Write config
fs.writeFile(filename, JSON.stringify(configData, null, 2), (err) => {
if (err) {
logger.error('Could not write db config to config file: ' + filename);
reject(err);
} else {
logger.debug('Wrote db configuration to config file: ' + filename);
resolve();
}
});
});
}
try { try {
appStart(); appStart();
} catch (err) { } catch (err) {
logger.error(err.message, err); logger.error(err.message, err);
process.exit(1); process.exit(1);
} }

View File

@ -118,6 +118,7 @@ const internalAccessList = {
// Sanity check that something crazy hasn't happened // Sanity check that something crazy hasn't happened
throw new error.InternalValidationError('Access List could not be updated, IDs do not match: ' + row.id + ' !== ' + data.id); throw new error.InternalValidationError('Access List could not be updated, IDs do not match: ' + row.id + ' !== ' + data.id);
} }
}) })
.then(() => { .then(() => {
// patch name if specified // patch name if specified
@ -204,7 +205,6 @@ const internalAccessList = {
}); });
} }
}) })
.then(internalNginx.reload)
.then(() => { .then(() => {
// Add to audit log // Add to audit log
return internalAuditLog.add(access, { return internalAuditLog.add(access, {

View File

@ -1,22 +1,19 @@
const _ = require('lodash'); const fs = require('fs');
const fs = require('fs'); const _ = require('lodash');
const https = require('https'); const logger = require('../logger').ssl;
const tempWrite = require('temp-write'); const error = require('../lib/error');
const moment = require('moment'); const certificateModel = require('../models/certificate');
const logger = require('../logger').ssl; const internalAuditLog = require('./audit-log');
const error = require('../lib/error'); const tempWrite = require('temp-write');
const utils = require('../lib/utils'); const utils = require('../lib/utils');
const certificateModel = require('../models/certificate'); const moment = require('moment');
const dnsPlugins = require('../global/certbot-dns-plugins'); const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG;
const internalAuditLog = require('./audit-log'); const le_staging = process.env.NODE_ENV !== 'production';
const internalNginx = require('./nginx'); const internalNginx = require('./nginx');
const internalHost = require('./host'); const internalHost = require('./host');
const letsencryptStaging = process.env.NODE_ENV !== 'production'; const certbot_command = '/usr/bin/certbot';
const letsencryptConfig = '/etc/letsencrypt.ini'; const le_config = '/etc/letsencrypt.ini';
const certbotCommand = 'certbot'; const dns_plugins = require('../global/certbot-dns-plugins');
const archiver = require('archiver');
const path = require('path');
const { isArray } = require('lodash');
function omissions() { function omissions() {
return ['is_deleted']; return ['is_deleted'];
@ -24,14 +21,14 @@ function omissions() {
const internalCertificate = { const internalCertificate = {
allowedSslFiles: ['certificate', 'certificate_key', 'intermediate_certificate'], allowed_ssl_files: ['certificate', 'certificate_key', 'intermediate_certificate'],
intervalTimeout: 1000 * 60 * 60, // 1 hour interval_timeout: 1000 * 60 * 60, // 1 hour
interval: null, interval: null,
intervalProcessing: false, interval_processing: false,
initTimer: () => { initTimer: () => {
logger.info('Let\'s Encrypt Renewal Timer initialized'); logger.info('Let\'s Encrypt Renewal Timer initialized');
internalCertificate.interval = setInterval(internalCertificate.processExpiringHosts, internalCertificate.intervalTimeout); internalCertificate.interval = setInterval(internalCertificate.processExpiringHosts, internalCertificate.interval_timeout);
// And do this now as well // And do this now as well
internalCertificate.processExpiringHosts(); internalCertificate.processExpiringHosts();
}, },
@ -40,15 +37,15 @@ const internalCertificate = {
* Triggered by a timer, this will check for expiring hosts and renew their ssl certs if required * Triggered by a timer, this will check for expiring hosts and renew their ssl certs if required
*/ */
processExpiringHosts: () => { processExpiringHosts: () => {
if (!internalCertificate.intervalProcessing) { if (!internalCertificate.interval_processing) {
internalCertificate.intervalProcessing = true; internalCertificate.interval_processing = true;
logger.info('Renewing SSL certs close to expiry...'); logger.info('Renewing SSL certs close to expiry...');
const cmd = certbotCommand + ' renew --non-interactive --quiet ' + let cmd = certbot_command + ' renew --non-interactive --quiet ' +
'--config "' + letsencryptConfig + '" ' + '--config "' + le_config + '" ' +
'--preferred-challenges "dns,http" ' + '--preferred-challenges "dns,http" ' +
'--disable-hook-validation ' + '--disable-hook-validation ' +
(letsencryptStaging ? '--staging' : ''); (le_staging ? '--staging' : '');
return utils.exec(cmd) return utils.exec(cmd)
.then((result) => { .then((result) => {
@ -96,11 +93,11 @@ const internalCertificate = {
}); });
}) })
.then(() => { .then(() => {
internalCertificate.intervalProcessing = false; internalCertificate.interval_processing = false;
}) })
.catch((err) => { .catch((err) => {
logger.error(err); logger.error(err);
internalCertificate.intervalProcessing = false; internalCertificate.interval_processing = false;
}); });
} }
}, },
@ -116,7 +113,7 @@ const internalCertificate = {
data.owner_user_id = access.token.getUserId(1); data.owner_user_id = access.token.getUserId(1);
if (data.provider === 'letsencrypt') { if (data.provider === 'letsencrypt') {
data.nice_name = data.domain_names.join(', '); data.nice_name = data.domain_names.sort().join(', ');
} }
return certificateModel return certificateModel
@ -171,7 +168,6 @@ const internalCertificate = {
// 3. Generate the LE config // 3. Generate the LE config
return internalNginx.generateLetsEncryptRequestConfig(certificate) return internalNginx.generateLetsEncryptRequestConfig(certificate)
.then(internalNginx.reload) .then(internalNginx.reload)
.then(async() => await new Promise((r) => setTimeout(r, 5000)))
.then(() => { .then(() => {
// 4. Request cert // 4. Request cert
return internalCertificate.requestLetsEncryptSsl(certificate); return internalCertificate.requestLetsEncryptSsl(certificate);
@ -220,13 +216,6 @@ const internalCertificate = {
return saved_row; return saved_row;
}); });
}); });
}).catch(async (error) => {
// Delete the certificate from the database if it was not created successfully
await certificateModel
.query()
.deleteById(certificate.id);
throw error;
}); });
} else { } else {
return certificate; return certificate;
@ -340,71 +329,6 @@ const internalCertificate = {
}); });
}, },
/**
* @param {Access} access
* @param {Object} data
* @param {Number} data.id
* @returns {Promise}
*/
download: (access, data) => {
return new Promise((resolve, reject) => {
access.can('certificates:get', data)
.then(() => {
return internalCertificate.get(access, data);
})
.then((certificate) => {
if (certificate.provider === 'letsencrypt') {
const zipDirectory = '/etc/letsencrypt/live/npm-' + data.id;
if (!fs.existsSync(zipDirectory)) {
throw new error.ItemNotFoundError('Certificate ' + certificate.nice_name + ' does not exists');
}
let certFiles = fs.readdirSync(zipDirectory)
.filter((fn) => fn.endsWith('.pem'))
.map((fn) => fs.realpathSync(path.join(zipDirectory, fn)));
const downloadName = 'npm-' + data.id + '-' + `${Date.now()}.zip`;
const opName = '/tmp/' + downloadName;
internalCertificate.zipFiles(certFiles, opName)
.then(() => {
logger.debug('zip completed : ', opName);
const resp = {
fileName: opName
};
resolve(resp);
}).catch((err) => reject(err));
} else {
throw new error.ValidationError('Only Let\'sEncrypt certificates can be downloaded');
}
}).catch((err) => reject(err));
});
},
/**
* @param {String} source
* @param {String} out
* @returns {Promise}
*/
zipFiles(source, out) {
const archive = archiver('zip', { zlib: { level: 9 } });
const stream = fs.createWriteStream(out);
return new Promise((resolve, reject) => {
source
.map((fl) => {
let fileName = path.basename(fl);
logger.debug(fl, 'added to certificate zip');
archive.file(fl, { name: fileName });
});
archive
.on('error', (err) => reject(err))
.pipe(stream);
stream.on('close', () => resolve());
archive.finalize();
});
},
/** /**
* @param {Access} access * @param {Access} access
* @param {Object} data * @param {Object} data
@ -477,7 +401,7 @@ const internalCertificate = {
// Query is used for searching // Query is used for searching
if (typeof search_query === 'string') { if (typeof search_query === 'string') {
query.where(function () { query.where(function () {
this.where('nice_name', 'like', '%' + search_query + '%'); this.where('name', 'like', '%' + search_query + '%');
}); });
} }
@ -517,9 +441,11 @@ const internalCertificate = {
* @returns {Promise} * @returns {Promise}
*/ */
writeCustomCert: (certificate) => { writeCustomCert: (certificate) => {
logger.info('Writing Custom Certificate:', certificate); if (debug_mode) {
logger.info('Writing Custom Certificate:', certificate);
}
const dir = '/data/custom_ssl/npm-' + certificate.id; let dir = '/data/custom_ssl/npm-' + certificate.id;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (certificate.provider === 'letsencrypt') { if (certificate.provider === 'letsencrypt') {
@ -527,9 +453,9 @@ const internalCertificate = {
return; return;
} }
let certData = certificate.meta.certificate; let cert_data = certificate.meta.certificate;
if (typeof certificate.meta.intermediate_certificate !== 'undefined') { if (typeof certificate.meta.intermediate_certificate !== 'undefined') {
certData = certData + '\n' + certificate.meta.intermediate_certificate; cert_data = cert_data + '\n' + certificate.meta.intermediate_certificate;
} }
try { try {
@ -541,7 +467,7 @@ const internalCertificate = {
return; return;
} }
fs.writeFile(dir + '/fullchain.pem', certData, function (err) { fs.writeFile(dir + '/fullchain.pem', cert_data, function (err) {
if (err) { if (err) {
reject(err); reject(err);
} else { } else {
@ -591,7 +517,7 @@ const internalCertificate = {
// Put file contents into an object // Put file contents into an object
let files = {}; let files = {};
_.map(data.files, (file, name) => { _.map(data.files, (file, name) => {
if (internalCertificate.allowedSslFiles.indexOf(name) !== -1) { if (internalCertificate.allowed_ssl_files.indexOf(name) !== -1) {
files[name] = file.data.toString(); files[name] = file.data.toString();
} }
}); });
@ -649,7 +575,7 @@ const internalCertificate = {
} }
_.map(data.files, (file, name) => { _.map(data.files, (file, name) => {
if (internalCertificate.allowedSslFiles.indexOf(name) !== -1) { if (internalCertificate.allowed_ssl_files.indexOf(name) !== -1) {
row.meta[name] = file.data.toString(); row.meta[name] = file.data.toString();
} }
}); });
@ -668,7 +594,7 @@ const internalCertificate = {
}); });
}) })
.then(() => { .then(() => {
return _.pick(row.meta, internalCertificate.allowedSslFiles); return _.pick(row.meta, internalCertificate.allowed_ssl_files);
}); });
}); });
}, },
@ -682,26 +608,18 @@ const internalCertificate = {
checkPrivateKey: (private_key) => { checkPrivateKey: (private_key) => {
return tempWrite(private_key, '/tmp') return tempWrite(private_key, '/tmp')
.then((filepath) => { .then((filepath) => {
return new Promise((resolve, reject) => { return utils.exec('openssl rsa -in ' + filepath + ' -check -noout')
const failTimeout = setTimeout(() => { .then((result) => {
reject(new error.ValidationError('Result Validation Error: Validation timed out. This could be due to the key being passphrase-protected.')); if (!result.toLowerCase().includes('key ok')) {
}, 10000); throw new error.ValidationError(result);
utils }
.exec('openssl pkey -in ' + filepath + ' -check -noout 2>&1 ')
.then((result) => { fs.unlinkSync(filepath);
clearTimeout(failTimeout); return true;
if (!result.toLowerCase().includes('key is valid')) { }).catch((err) => {
reject(new error.ValidationError('Result Validation Error: ' + result)); fs.unlinkSync(filepath);
} throw new error.ValidationError('Certificate Key is not valid (' + err.message + ')', err);
fs.unlinkSync(filepath); });
resolve(true);
})
.catch((err) => {
clearTimeout(failTimeout);
fs.unlinkSync(filepath);
reject(new error.ValidationError('Certificate Key is not valid (' + err.message + ')', err));
});
});
}); });
}, },
@ -716,9 +634,9 @@ const internalCertificate = {
return tempWrite(certificate, '/tmp') return tempWrite(certificate, '/tmp')
.then((filepath) => { .then((filepath) => {
return internalCertificate.getCertificateInfoFromFile(filepath, throw_expired) return internalCertificate.getCertificateInfoFromFile(filepath, throw_expired)
.then((certData) => { .then((cert_data) => {
fs.unlinkSync(filepath); fs.unlinkSync(filepath);
return certData; return cert_data;
}).catch((err) => { }).catch((err) => {
fs.unlinkSync(filepath); fs.unlinkSync(filepath);
throw err; throw err;
@ -734,33 +652,33 @@ const internalCertificate = {
* @param {Boolean} [throw_expired] Throw when the certificate is out of date * @param {Boolean} [throw_expired] Throw when the certificate is out of date
*/ */
getCertificateInfoFromFile: (certificate_file, throw_expired) => { getCertificateInfoFromFile: (certificate_file, throw_expired) => {
let certData = {}; let cert_data = {};
return utils.exec('openssl x509 -in ' + certificate_file + ' -subject -noout') return utils.exec('openssl x509 -in ' + certificate_file + ' -subject -noout')
.then((result) => { .then((result) => {
// subject=CN = something.example.com // subject=CN = something.example.com
const regex = /(?:subject=)?[^=]+=\s+(\S+)/gim; let regex = /(?:subject=)?[^=]+=\s+(\S+)/gim;
const match = regex.exec(result); let match = regex.exec(result);
if (typeof match[1] === 'undefined') { if (typeof match[1] === 'undefined') {
throw new error.ValidationError('Could not determine subject from certificate: ' + result); throw new error.ValidationError('Could not determine subject from certificate: ' + result);
} }
certData['cn'] = match[1]; cert_data['cn'] = match[1];
}) })
.then(() => { .then(() => {
return utils.exec('openssl x509 -in ' + certificate_file + ' -issuer -noout'); return utils.exec('openssl x509 -in ' + certificate_file + ' -issuer -noout');
}) })
.then((result) => { .then((result) => {
// issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 // issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
const regex = /^(?:issuer=)?(.*)$/gim; let regex = /^(?:issuer=)?(.*)$/gim;
const match = regex.exec(result); let match = regex.exec(result);
if (typeof match[1] === 'undefined') { if (typeof match[1] === 'undefined') {
throw new error.ValidationError('Could not determine issuer from certificate: ' + result); throw new error.ValidationError('Could not determine issuer from certificate: ' + result);
} }
certData['issuer'] = match[1]; cert_data['issuer'] = match[1];
}) })
.then(() => { .then(() => {
return utils.exec('openssl x509 -in ' + certificate_file + ' -dates -noout'); return utils.exec('openssl x509 -in ' + certificate_file + ' -dates -noout');
@ -768,39 +686,39 @@ const internalCertificate = {
.then((result) => { .then((result) => {
// notBefore=Jul 14 04:04:29 2018 GMT // notBefore=Jul 14 04:04:29 2018 GMT
// notAfter=Oct 12 04:04:29 2018 GMT // notAfter=Oct 12 04:04:29 2018 GMT
let validFrom = null; let valid_from = null;
let validTo = null; let valid_to = null;
const lines = result.split('\n'); let lines = result.split('\n');
lines.map(function (str) { lines.map(function (str) {
const regex = /^(\S+)=(.*)$/gim; let regex = /^(\S+)=(.*)$/gim;
const match = regex.exec(str.trim()); let match = regex.exec(str.trim());
if (match && typeof match[2] !== 'undefined') { if (match && typeof match[2] !== 'undefined') {
const date = parseInt(moment(match[2], 'MMM DD HH:mm:ss YYYY z').format('X'), 10); let date = parseInt(moment(match[2], 'MMM DD HH:mm:ss YYYY z').format('X'), 10);
if (match[1].toLowerCase() === 'notbefore') { if (match[1].toLowerCase() === 'notbefore') {
validFrom = date; valid_from = date;
} else if (match[1].toLowerCase() === 'notafter') { } else if (match[1].toLowerCase() === 'notafter') {
validTo = date; valid_to = date;
} }
} }
}); });
if (!validFrom || !validTo) { if (!valid_from || !valid_to) {
throw new error.ValidationError('Could not determine dates from certificate: ' + result); throw new error.ValidationError('Could not determine dates from certificate: ' + result);
} }
if (throw_expired && validTo < parseInt(moment().format('X'), 10)) { if (throw_expired && valid_to < parseInt(moment().format('X'), 10)) {
throw new error.ValidationError('Certificate has expired'); throw new error.ValidationError('Certificate has expired');
} }
certData['dates'] = { cert_data['dates'] = {
from: validFrom, from: valid_from,
to: validTo to: valid_to
}; };
return certData; return cert_data;
}).catch((err) => { }).catch((err) => {
throw new error.ValidationError('Certificate is not valid (' + err.message + ')', err); throw new error.ValidationError('Certificate is not valid (' + err.message + ')', err);
}); });
@ -814,7 +732,7 @@ const internalCertificate = {
* @returns {Object} * @returns {Object}
*/ */
cleanMeta: function (meta, remove) { cleanMeta: function (meta, remove) {
internalCertificate.allowedSslFiles.map((key) => { internalCertificate.allowed_ssl_files.map((key) => {
if (typeof meta[key] !== 'undefined' && meta[key]) { if (typeof meta[key] !== 'undefined' && meta[key]) {
if (remove) { if (remove) {
delete meta[key]; delete meta[key];
@ -828,24 +746,24 @@ const internalCertificate = {
}, },
/** /**
* Request a certificate using the http challenge
* @param {Object} certificate the certificate row * @param {Object} certificate the certificate row
* @returns {Promise} * @returns {Promise}
*/ */
requestLetsEncryptSsl: (certificate) => { requestLetsEncryptSsl: (certificate) => {
logger.info('Requesting Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', ')); logger.info('Requesting Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
const cmd = certbotCommand + ' certonly ' + let cmd = certbot_command + ' certonly --non-interactive ' +
'--config "' + letsencryptConfig + '" ' + '--config "' + le_config + '" ' +
'--cert-name "npm-' + certificate.id + '" ' + '--cert-name "npm-' + certificate.id + '" ' +
'--agree-tos ' + '--agree-tos ' +
'--authenticator webroot ' +
'--email "' + certificate.meta.letsencrypt_email + '" ' + '--email "' + certificate.meta.letsencrypt_email + '" ' +
'--preferred-challenges "dns,http" ' + '--preferred-challenges "dns,http" ' +
'--domains "' + certificate.domain_names.join(',') + '" ' + '--domains "' + certificate.domain_names.join(',') + '" ' +
(letsencryptStaging ? '--staging' : ''); (le_staging ? '--staging' : '');
logger.info('Command:', cmd); if (debug_mode) {
logger.info('Command:', cmd);
}
return utils.exec(cmd) return utils.exec(cmd)
.then((result) => { .then((result) => {
@ -855,14 +773,14 @@ const internalCertificate = {
}, },
/** /**
* @param {Object} certificate the certificate row * @param {Object} certificate the certificate row
* @param {String} dns_provider the dns provider name (key used in `certbot-dns-plugins.js`) * @param {String} dns_provider the dns provider name (key used in `certbot-dns-plugins.js`)
* @param {String | null} credentials the content of this providers credentials file * @param {String | null} credentials the content of this providers credentials file
* @param {String} propagation_seconds the cloudflare api token * @param {String} propagation_seconds the cloudflare api token
* @returns {Promise} * @returns {Promise}
*/ */
requestLetsEncryptSslWithDnsChallenge: (certificate) => { requestLetsEncryptSslWithDnsChallenge: (certificate) => {
const dns_plugin = dnsPlugins[certificate.meta.dns_provider]; const dns_plugin = dns_plugins[certificate.meta.dns_provider];
if (!dns_plugin) { if (!dns_plugin) {
throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`); throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`);
@ -870,30 +788,23 @@ const internalCertificate = {
logger.info(`Requesting Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`); 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; const credentials_loc = '/etc/letsencrypt/credentials-' + certificate.id;
// Escape single quotes and backslashes const credentials_cmd = 'echo \'' + certificate.meta.dns_provider_credentials.replace('\'', '\\\'') + '\' > \'' + credentials_loc + '\' && chmod 600 \'' + credentials_loc + '\'';
const escapedCredentials = certificate.meta.dns_provider_credentials.replaceAll('\'', '\\\'').replaceAll('\\', '\\\\'); const prepare_cmd = 'pip3 install ' + dns_plugin.package_name + '==' + dns_plugin.package_version;
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';
}
// Whether the plugin has a --<name>-credentials argument // Whether the plugin has a --<name>-credentials argument
const hasConfigArg = certificate.meta.dns_provider !== 'route53'; const has_config_arg = certificate.meta.dns_provider !== 'route53';
let mainCmd = certbotCommand + ' certonly ' + let main_cmd =
'--config "' + letsencryptConfig + '" ' + certbot_command + ' certonly --non-interactive ' +
'--cert-name "npm-' + certificate.id + '" ' + '--cert-name "npm-' + certificate.id + '" ' +
'--agree-tos ' + '--agree-tos ' +
'--email "' + certificate.meta.letsencrypt_email + '" ' + '--email "' + certificate.meta.letsencrypt_email + '" ' +
'--domains "' + certificate.domain_names.join(',') + '" ' + '--domains "' + certificate.domain_names.join(',') + '" ' +
'--authenticator ' + dns_plugin.full_plugin_name + ' ' + '--authenticator ' + dns_plugin.full_plugin_name + ' ' +
( (
hasConfigArg has_config_arg
? '--' + dns_plugin.full_plugin_name + '-credentials "' + credentialsLocation + '"' ? '--' + dns_plugin.full_plugin_name + '-credentials "' + credentials_loc + '"'
: '' : ''
) + ) +
( (
@ -901,30 +812,30 @@ const internalCertificate = {
? ' --' + dns_plugin.full_plugin_name + '-propagation-seconds ' + certificate.meta.propagation_seconds ? ' --' + dns_plugin.full_plugin_name + '-propagation-seconds ' + certificate.meta.propagation_seconds
: '' : ''
) + ) +
(letsencryptStaging ? ' --staging' : ''); (le_staging ? ' --staging' : '');
// Prepend the path to the credentials file as an environment variable // Prepend the path to the credentials file as an environment variable
if (certificate.meta.dns_provider === 'route53') { if (certificate.meta.dns_provider === 'route53') {
mainCmd = 'AWS_CONFIG_FILE=\'' + credentialsLocation + '\' ' + mainCmd; main_cmd = 'AWS_CONFIG_FILE=\'' + credentials_loc + '\' ' + main_cmd;
} }
logger.info('Command:', `${credentialsCmd} && ${prepareCmd} && ${mainCmd}`); const teardown_cmd = `rm '${credentials_loc}'`;
return utils.exec(credentialsCmd) if (debug_mode) {
logger.info('Command:', `${credentials_cmd} && ${prepare_cmd} && ${main_cmd} && ${teardown_cmd}`);
}
return utils.exec(credentials_cmd)
.then(() => { .then(() => {
return utils.exec(prepareCmd) return utils.exec(prepare_cmd)
.then(() => { .then(() => {
return utils.exec(mainCmd) return utils.exec(main_cmd)
.then(async (result) => { .then(async (result) => {
await utils.exec(teardown_cmd);
logger.info(result); logger.info(result);
return result; return result;
}); });
}); });
}).catch(async (err) => {
// Don't fail if file does not exist
const delete_credentialsCmd = `rm -f '${credentialsLocation}' || true`;
await utils.exec(delete_credentialsCmd);
throw err;
}); });
}, },
@ -942,7 +853,7 @@ const internalCertificate = {
}) })
.then((certificate) => { .then((certificate) => {
if (certificate.provider === 'letsencrypt') { if (certificate.provider === 'letsencrypt') {
const renewMethod = certificate.meta.dns_challenge ? internalCertificate.renewLetsEncryptSslWithDnsChallenge : internalCertificate.renewLetsEncryptSsl; let renewMethod = certificate.meta.dns_challenge ? internalCertificate.renewLetsEncryptSslWithDnsChallenge : internalCertificate.renewLetsEncryptSsl;
return renewMethod(certificate) return renewMethod(certificate)
.then(() => { .then(() => {
@ -980,15 +891,16 @@ const internalCertificate = {
renewLetsEncryptSsl: (certificate) => { renewLetsEncryptSsl: (certificate) => {
logger.info('Renewing Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', ')); logger.info('Renewing Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
const cmd = certbotCommand + ' renew --force-renewal ' + let cmd = certbot_command + ' renew --non-interactive ' +
'--config "' + letsencryptConfig + '" ' + '--config "' + le_config + '" ' +
'--cert-name "npm-' + certificate.id + '" ' + '--cert-name "npm-' + certificate.id + '" ' +
'--preferred-challenges "dns,http" ' + '--preferred-challenges "dns,http" ' +
'--no-random-sleep-on-renew ' +
'--disable-hook-validation ' + '--disable-hook-validation ' +
(letsencryptStaging ? '--staging' : ''); (le_staging ? '--staging' : '');
logger.info('Command:', cmd); if (debug_mode) {
logger.info('Command:', cmd);
}
return utils.exec(cmd) return utils.exec(cmd)
.then((result) => { .then((result) => {
@ -1002,7 +914,7 @@ const internalCertificate = {
* @returns {Promise} * @returns {Promise}
*/ */
renewLetsEncryptSslWithDnsChallenge: (certificate) => { renewLetsEncryptSslWithDnsChallenge: (certificate) => {
const dns_plugin = dnsPlugins[certificate.meta.dns_provider]; const dns_plugin = dns_plugins[certificate.meta.dns_provider];
if (!dns_plugin) { if (!dns_plugin) {
throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`); throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`);
@ -1010,25 +922,38 @@ const internalCertificate = {
logger.info(`Renewing Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`); logger.info(`Renewing Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
let mainCmd = certbotCommand + ' renew ' + const credentials_loc = '/etc/letsencrypt/credentials-' + certificate.id;
'--config "' + letsencryptConfig + '" ' + const credentials_cmd = 'echo \'' + certificate.meta.dns_provider_credentials.replace('\'', '\\\'') + '\' > \'' + credentials_loc + '\' && chmod 600 \'' + credentials_loc + '\'';
const prepare_cmd = 'pip3 install ' + dns_plugin.package_name + '==' + dns_plugin.package_version;
let main_cmd =
certbot_command + ' renew --non-interactive ' +
'--cert-name "npm-' + certificate.id + '" ' + '--cert-name "npm-' + certificate.id + '" ' +
'--disable-hook-validation ' + '--disable-hook-validation' +
'--no-random-sleep-on-renew ' + (le_staging ? ' --staging' : '');
(letsencryptStaging ? ' --staging' : '');
// Prepend the path to the credentials file as an environment variable // Prepend the path to the credentials file as an environment variable
if (certificate.meta.dns_provider === 'route53') { if (certificate.meta.dns_provider === 'route53') {
const credentialsLocation = '/etc/letsencrypt/credentials/credentials-' + certificate.id; main_cmd = 'AWS_CONFIG_FILE=\'' + credentials_loc + '\' ' + main_cmd;
mainCmd = 'AWS_CONFIG_FILE=\'' + credentialsLocation + '\' ' + mainCmd;
} }
logger.info('Command:', mainCmd); const teardown_cmd = `rm '${credentials_loc}'`;
return utils.exec(mainCmd) if (debug_mode) {
.then(async (result) => { logger.info('Command:', `${credentials_cmd} && ${prepare_cmd} && ${main_cmd} && ${teardown_cmd}`);
logger.info(result); }
return result;
return utils.exec(credentials_cmd)
.then(() => {
return utils.exec(prepare_cmd)
.then(() => {
return utils.exec(main_cmd)
.then(async (result) => {
await utils.exec(teardown_cmd);
logger.info(result);
return result;
});
});
}); });
}, },
@ -1040,25 +965,27 @@ const internalCertificate = {
revokeLetsEncryptSsl: (certificate, throw_errors) => { revokeLetsEncryptSsl: (certificate, throw_errors) => {
logger.info('Revoking Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', ')); logger.info('Revoking Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
const mainCmd = certbotCommand + ' revoke ' + let cmd = certbot_command + ' revoke --non-interactive ' +
'--config "' + letsencryptConfig + '" ' +
'--cert-path "/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' + '--cert-path "/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' +
'--delete-after-revoke ' + '--delete-after-revoke ' +
(letsencryptStaging ? '--staging' : ''); (le_staging ? '--staging' : '');
// Don't fail command if file does not exist if (debug_mode) {
const delete_credentialsCmd = `rm -f '/etc/letsencrypt/credentials/credentials-${certificate.id}' || true`; logger.info('Command:', cmd);
}
logger.info('Command:', mainCmd + '; ' + delete_credentialsCmd); return utils.exec(cmd)
.then((result) => {
return utils.exec(mainCmd) if (debug_mode) {
.then(async (result) => { logger.info('Command:', cmd);
await utils.exec(delete_credentialsCmd); }
logger.info(result); logger.info(result);
return result; return result;
}) })
.catch((err) => { .catch((err) => {
logger.error(err.message); if (debug_mode) {
logger.error(err.message);
}
if (throw_errors) { if (throw_errors) {
throw err; throw err;
@ -1071,9 +998,9 @@ const internalCertificate = {
* @returns {Boolean} * @returns {Boolean}
*/ */
hasLetsEncryptSslCerts: (certificate) => { hasLetsEncryptSslCerts: (certificate) => {
const letsencryptPath = '/etc/letsencrypt/live/npm-' + certificate.id; let le_path = '/etc/letsencrypt/live/npm-' + certificate.id;
return fs.existsSync(letsencryptPath + '/fullchain.pem') && fs.existsSync(letsencryptPath + '/privkey.pem'); return fs.existsSync(le_path + '/fullchain.pem') && fs.existsSync(le_path + '/privkey.pem');
}, },
/** /**
@ -1134,94 +1061,6 @@ const internalCertificate = {
} else { } else {
return Promise.resolve(); 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

@ -106,7 +106,7 @@ const internalHost = {
response_object.total_count += response_object.redirection_hosts.length; response_object.total_count += response_object.redirection_hosts.length;
} }
if (promises_results[2]) { if (promises_results[1]) {
// Dead Hosts // Dead Hosts
response_object.dead_hosts = internalHost._getHostsWithDomains(promises_results[2], domain_names); response_object.dead_hosts = internalHost._getHostsWithDomains(promises_results[2], domain_names);
response_object.total_count += response_object.dead_hosts.length; response_object.total_count += response_object.dead_hosts.length;
@ -158,7 +158,7 @@ const internalHost = {
} }
} }
if (promises_results[2]) { if (promises_results[1]) {
// Dead Hosts // Dead Hosts
if (internalHost._checkHostnameRecordsTaken(hostname, promises_results[2], ignore_type === 'dead' && ignore_id ? ignore_id : 0)) { if (internalHost._checkHostnameRecordsTaken(hostname, promises_results[2], ignore_type === 'dead' && ignore_id ? ignore_id : 0)) {
is_taken = true; is_taken = true;

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_V4_URL = 'https://www.cloudflare.com/ips-v4';
const CLOUDFARE_V6_URL = 'https://www.cloudflare.com/ips-v6'; const CLOUDFARE_V6_URL = 'https://www.cloudflare.com/ips-v6';
const regIpV4 = /^(\d+\.?){4}\/\d+/;
const regIpV6 = /^(([\da-fA-F]+)?:)+\/\d+/;
const internalIpRanges = { const internalIpRanges = {
interval_timeout: 1000 * 60 * 60 * 6, // 6 hours interval_timeout: 1000 * 60 * 60 * 6, // 6 hours
@ -77,14 +74,14 @@ const internalIpRanges = {
return internalIpRanges.fetchUrl(CLOUDFARE_V4_URL); return internalIpRanges.fetchUrl(CLOUDFARE_V4_URL);
}) })
.then((cloudfare_data) => { .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]; ip_ranges = [... ip_ranges, ... items];
}) })
.then(() => { .then(() => {
return internalIpRanges.fetchUrl(CLOUDFARE_V6_URL); return internalIpRanges.fetchUrl(CLOUDFARE_V6_URL);
}) })
.then((cloudfare_data) => { .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]; ip_ranges = [... ip_ranges, ... items];
}) })
.then(() => { .then(() => {

View File

@ -136,8 +136,6 @@ const internalNginx = {
* @returns {Promise} * @returns {Promise}
*/ */
renderLocations: (host) => { renderLocations: (host) => {
//logger.info('host = ' + JSON.stringify(host, null, 2));
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let template; let template;
@ -148,18 +146,12 @@ const internalNginx = {
return; return;
} }
let renderer = new Liquid({ let renderer = new Liquid();
root: __dirname + '/../templates/'
});
let renderedLocations = ''; let renderedLocations = '';
const locationRendering = async () => { const locationRendering = async () => {
for (let i = 0; i < host.locations.length; i++) { for (let i = 0; i < host.locations.length; i++) {
let locationCopy = Object.assign({}, {access_list_id: host.access_list_id}, {certificate_id: host.certificate_id}, let locationCopy = Object.assign({}, host.locations[i]);
{ssl_forced: host.ssl_forced}, {caching_enabled: host.caching_enabled}, {block_exploits: host.block_exploits},
{allow_websocket_upgrade: host.allow_websocket_upgrade}, {http2_support: host.http2_support},
{hsts_enabled: host.hsts_enabled}, {hsts_subdomains: host.hsts_subdomains}, {access_list: host.access_list},
{certificate: host.certificate}, host.locations[i]);
if (locationCopy.forward_host.indexOf('/') > -1) { if (locationCopy.forward_host.indexOf('/') > -1) {
const splitted = locationCopy.forward_host.split('/'); const splitted = locationCopy.forward_host.split('/');
@ -168,16 +160,12 @@ const internalNginx = {
locationCopy.forward_path = `/${splitted.join('/')}`; locationCopy.forward_path = `/${splitted.join('/')}`;
} }
//logger.info('locationCopy = ' + JSON.stringify(locationCopy, null, 2));
// eslint-disable-next-line // eslint-disable-next-line
renderedLocations += await renderer.parseAndRender(template, locationCopy); renderedLocations += await renderer.parseAndRender(template, locationCopy);
} }
}; };
locationRendering().then(() => resolve(renderedLocations)); locationRendering().then(() => resolve(renderedLocations));
}); });
}, },
@ -193,8 +181,6 @@ const internalNginx = {
logger.info('Generating ' + host_type + ' Config:', host); logger.info('Generating ' + host_type + ' Config:', host);
} }
// logger.info('host = ' + JSON.stringify(host, null, 2));
let renderEngine = new Liquid({ let renderEngine = new Liquid({
root: __dirname + '/../templates/' root: __dirname + '/../templates/'
}); });
@ -222,7 +208,6 @@ const internalNginx = {
} }
if (host.locations) { if (host.locations) {
//logger.info ('host.locations = ' + JSON.stringify(host.locations, null, 2));
origLocations = [].concat(host.locations); origLocations = [].concat(host.locations);
locationsPromise = internalNginx.renderLocations(host).then((renderedLocations) => { locationsPromise = internalNginx.renderLocations(host).then((renderedLocations) => {
host.locations = renderedLocations; host.locations = renderedLocations;

View File

@ -189,10 +189,6 @@ const internalProxyHost = {
expand: ['owner', 'certificate', 'access_list.[clients,items]'] expand: ['owner', 'certificate', 'access_list.[clients,items]']
}) })
.then((row) => { .then((row) => {
if (!row.enabled) {
// No need to add nginx config if host is disabled
return row;
}
// Configure nginx // Configure nginx
return internalNginx.configure(proxyHostModel, 'proxy_host', row) return internalNginx.configure(proxyHostModel, 'proxy_host', row)
.then((new_meta) => { .then((new_meta) => {

View File

@ -1,41 +0,0 @@
const migrate_name = 'redirection_scheme';
const logger = require('../logger').migrate;
/**
* Migrate
*
* @see http://knexjs.org/#Schema
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.up = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Up...');
return knex.schema.table('redirection_host', (table) => {
table.string('forward_scheme').notNull().defaultTo('$scheme');
})
.then(function () {
logger.info('[' + migrate_name + '] redirection_host Table altered');
});
};
/**
* Undo Migrate
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.down = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Down...');
return knex.schema.table('redirection_host', (table) => {
table.dropColumn('forward_scheme');
})
.then(function () {
logger.info('[' + migrate_name + '] redirection_host Table altered');
});
};

View File

@ -1,41 +0,0 @@
const migrate_name = 'redirection_status_code';
const logger = require('../logger').migrate;
/**
* Migrate
*
* @see http://knexjs.org/#Schema
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.up = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Up...');
return knex.schema.table('redirection_host', (table) => {
table.integer('forward_http_code').notNull().unsigned().defaultTo(302);
})
.then(function () {
logger.info('[' + migrate_name + '] redirection_host Table altered');
});
};
/**
* Undo Migrate
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.down = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Down...');
return knex.schema.table('redirection_host', (table) => {
table.dropColumn('forward_http_code');
})
.then(function () {
logger.info('[' + migrate_name + '] redirection_host Table altered');
});
};

View File

@ -1,40 +0,0 @@
const migrate_name = 'stream_domain';
const logger = require('../logger').migrate;
/**
* Migrate
*
* @see http://knexjs.org/#Schema
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.up = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Up...');
return knex.schema.table('stream', (table) => {
table.renameColumn('forward_ip', 'forwarding_host');
})
.then(function () {
logger.info('[' + migrate_name + '] stream Table altered');
});
};
/**
* Undo Migrate
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.down = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Down...');
return knex.schema.table('stream', (table) => {
table.renameColumn('forwarding_host', 'forward_ip');
})
.then(function () {
logger.info('[' + migrate_name + '] stream Table altered');
});
};

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

@ -4,23 +4,15 @@
*/ */
const _ = require('lodash'); const _ = require('lodash');
const config = require('config');
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
const crypto = require('crypto'); const crypto = require('crypto');
const error = require('../lib/error'); const error = require('../lib/error');
const ALGO = 'RS256'; const ALGO = 'RS256';
let public_key = null;
let private_key = null;
function checkJWTKeyPair() {
if (!public_key || !private_key) {
let config = require('config');
public_key = config.get('jwt.pub');
private_key = config.get('jwt.key');
}
}
module.exports = function () { module.exports = function () {
const public_key = config.get('jwt.pub');
const private_key = config.get('jwt.key');
let token_data = {}; let token_data = {};
@ -40,8 +32,6 @@ module.exports = function () {
.toString('base64') .toString('base64')
.substr(-8); .substr(-8);
checkJWTKeyPair();
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
jwt.sign(payload, private_key, options, (err, token) => { jwt.sign(payload, private_key, options, (err, token) => {
if (err) { if (err) {
@ -63,7 +53,6 @@ module.exports = function () {
*/ */
load: function (token) { load: function (token) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
checkJWTKeyPair();
try { try {
if (!token || token === null || token === 'null') { if (!token || token === null || token === 'null') {
reject(new error.AuthError('Empty token')); reject(new error.AuthError('Empty token'));

View File

@ -5,29 +5,33 @@
"main": "js/index.js", "main": "js/index.js",
"dependencies": { "dependencies": {
"ajv": "^6.12.0", "ajv": "^6.12.0",
"archiver": "^5.3.0",
"batchflow": "^0.4.0", "batchflow": "^0.4.0",
"bcrypt": "^5.0.0", "bcrypt": "^5.0.0",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"compression": "^1.7.4", "compression": "^1.7.4",
"config": "^3.3.1", "config": "^3.3.1",
"diskdb": "^0.1.17",
"express": "^4.17.1", "express": "^4.17.1",
"express-fileupload": "^1.1.9", "express-fileupload": "^1.1.9",
"gravatar": "^1.8.0", "gravatar": "^1.8.0",
"html-entities": "^1.2.1",
"json-schema-ref-parser": "^8.0.0", "json-schema-ref-parser": "^8.0.0",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"knex": "^0.20.13", "knex": "^0.20.13",
"liquidjs": "^9.11.10", "liquidjs": "^9.11.10",
"lodash": "^4.17.21", "lodash": "^4.17.19",
"moment": "^2.29.4", "moment": "^2.24.0",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"node-rsa": "^1.0.8", "node-rsa": "^1.0.8",
"nodemon": "^2.0.2", "nodemon": "^2.0.2",
"objection": "^2.2.16", "objection": "^2.1.3",
"path": "^0.12.7", "path": "^0.12.7",
"pg": "^7.12.1",
"restler": "^3.4.0",
"signale": "^1.4.0", "signale": "^1.4.0",
"sqlite3": "^4.1.1", "sqlite3": "^4.1.1",
"temp-write": "^4.0.0" "temp-write": "^4.0.0",
"unix-timestamp": "^0.2.0"
}, },
"signale": { "signale": {
"displayDate": true, "displayDate": true,

View File

@ -68,32 +68,6 @@ router
.catch(next); .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 * Specific certificate
* *
@ -235,34 +209,6 @@ router
.catch(next); .catch(next);
}); });
/**
* Download LE Certs
*
* /api/nginx/certificates/123/download
*/
router
.route('/:certificate_id/download')
.options((req, res) => {
res.sendStatus(204);
})
.all(jwtdecode())
/**
* GET /api/nginx/certificates/123/download
*
* Renew certificate
*/
.get((req, res, next) => {
internalCertificate.download(res.locals.access, {
id: parseInt(req.params.certificate_id, 10)
})
.then((result) => {
res.status(200)
.download(result.fileName);
})
.catch(next);
});
/** /**
* Validate Certs before saving * Validate Certs before saving
* *

View File

@ -153,7 +153,7 @@
"example": "john@example.com", "example": "john@example.com",
"format": "email", "format": "email",
"type": "string", "type": "string",
"minLength": 6, "minLength": 8,
"maxLength": 100 "maxLength": 100
}, },
"password": { "password": {
@ -179,19 +179,6 @@
"pattern": "^(?:\\*\\.)?(?:[^.*]+\\.?)+[^.]$" "pattern": "^(?:\\*\\.)?(?:[^.*]+\\.?)+[^.]$"
} }
}, },
"http_code": {
"description": "Redirect HTTP Status Code",
"example": 302,
"type": "integer",
"minimum": 300,
"maximum": 308
},
"scheme": {
"description": "RFC Protocol",
"example": "HTTPS or $scheme",
"type": "string",
"minLength": 4
},
"enabled": { "enabled": {
"description": "Is Enabled", "description": "Is Enabled",
"example": true, "example": true,

View File

@ -157,17 +157,6 @@
"targetSchema": { "targetSchema": {
"type": "boolean" "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

@ -18,12 +18,6 @@
"domain_names": { "domain_names": {
"$ref": "../definitions.json#/definitions/domain_names" "$ref": "../definitions.json#/definitions/domain_names"
}, },
"forward_http_code": {
"$ref": "../definitions.json#/definitions/http_code"
},
"forward_scheme": {
"$ref": "../definitions.json#/definitions/scheme"
},
"forward_domain_name": { "forward_domain_name": {
"$ref": "../definitions.json#/definitions/domain_name" "$ref": "../definitions.json#/definitions/domain_name"
}, },
@ -73,12 +67,6 @@
"domain_names": { "domain_names": {
"$ref": "#/definitions/domain_names" "$ref": "#/definitions/domain_names"
}, },
"forward_http_code": {
"$ref": "#/definitions/forward_http_code"
},
"forward_scheme": {
"$ref": "#/definitions/forward_scheme"
},
"forward_domain_name": { "forward_domain_name": {
"$ref": "#/definitions/forward_domain_name" "$ref": "#/definitions/forward_domain_name"
}, },
@ -146,20 +134,12 @@
"additionalProperties": false, "additionalProperties": false,
"required": [ "required": [
"domain_names", "domain_names",
"forward_scheme",
"forward_http_code",
"forward_domain_name" "forward_domain_name"
], ],
"properties": { "properties": {
"domain_names": { "domain_names": {
"$ref": "#/definitions/domain_names" "$ref": "#/definitions/domain_names"
}, },
"forward_http_code": {
"$ref": "#/definitions/forward_http_code"
},
"forward_scheme": {
"$ref": "#/definitions/forward_scheme"
},
"forward_domain_name": { "forward_domain_name": {
"$ref": "#/definitions/forward_domain_name" "$ref": "#/definitions/forward_domain_name"
}, },
@ -215,12 +195,6 @@
"domain_names": { "domain_names": {
"$ref": "#/definitions/domain_names" "$ref": "#/definitions/domain_names"
}, },
"forward_http_code": {
"$ref": "#/definitions/forward_http_code"
},
"forward_scheme": {
"$ref": "#/definitions/forward_scheme"
},
"forward_domain_name": { "forward_domain_name": {
"$ref": "#/definitions/forward_domain_name" "$ref": "#/definitions/forward_domain_name"
}, },

View File

@ -20,20 +20,9 @@
"minimum": 1, "minimum": 1,
"maximum": 65535 "maximum": 65535
}, },
"forwarding_host": { "forward_ip": {
"anyOf": [ "type": "string",
{ "format": "ipv4"
"$ref": "../definitions.json#/definitions/domain_name"
},
{
"type": "string",
"format": "ipv4"
},
{
"type": "string",
"format": "ipv6"
}
]
}, },
"forwarding_port": { "forwarding_port": {
"type": "integer", "type": "integer",
@ -66,8 +55,8 @@
"incoming_port": { "incoming_port": {
"$ref": "#/definitions/incoming_port" "$ref": "#/definitions/incoming_port"
}, },
"forwarding_host": { "forward_ip": {
"$ref": "#/definitions/forwarding_host" "$ref": "#/definitions/forward_ip"
}, },
"forwarding_port": { "forwarding_port": {
"$ref": "#/definitions/forwarding_port" "$ref": "#/definitions/forwarding_port"
@ -118,15 +107,15 @@
"additionalProperties": false, "additionalProperties": false,
"required": [ "required": [
"incoming_port", "incoming_port",
"forwarding_host", "forward_ip",
"forwarding_port" "forwarding_port"
], ],
"properties": { "properties": {
"incoming_port": { "incoming_port": {
"$ref": "#/definitions/incoming_port" "$ref": "#/definitions/incoming_port"
}, },
"forwarding_host": { "forward_ip": {
"$ref": "#/definitions/forwarding_host" "$ref": "#/definitions/forward_ip"
}, },
"forwarding_port": { "forwarding_port": {
"$ref": "#/definitions/forwarding_port" "$ref": "#/definitions/forwarding_port"
@ -165,8 +154,8 @@
"incoming_port": { "incoming_port": {
"$ref": "#/definitions/incoming_port" "$ref": "#/definitions/incoming_port"
}, },
"forwarding_host": { "forward_ip": {
"$ref": "#/definitions/forwarding_host" "$ref": "#/definitions/forward_ip"
}, },
"forwarding_port": { "forwarding_port": {
"$ref": "#/definitions/forwarding_port" "$ref": "#/definitions/forwarding_port"

View File

@ -2,13 +2,10 @@ const fs = require('fs');
const NodeRSA = require('node-rsa'); const NodeRSA = require('node-rsa');
const config = require('config'); const config = require('config');
const logger = require('./logger').setup; const logger = require('./logger').setup;
const certificateModel = require('./models/certificate');
const userModel = require('./models/user'); const userModel = require('./models/user');
const userPermissionModel = require('./models/user_permission'); const userPermissionModel = require('./models/user_permission');
const utils = require('./lib/utils');
const authModel = require('./models/auth'); const authModel = require('./models/auth');
const settingModel = require('./models/setting'); const settingModel = require('./models/setting');
const dns_plugins = require('./global/certbot-dns-plugins');
const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG; const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG;
/** /**
@ -51,8 +48,9 @@ const setupJwt = () => {
reject(err); reject(err);
} else { } else {
logger.info('Wrote JWT key pair to config file: ' + filename); logger.info('Wrote JWT key pair to config file: ' + filename);
delete require.cache[require.resolve('config')];
resolve(); logger.warn('Restarting interface to apply new configuration');
process.exit(0);
} }
}); });
} else { } else {
@ -157,86 +155,8 @@ const setupDefaultSettings = () => {
}); });
}; };
/**
* Installs all Certbot plugins which are required for an installed certificate
*
* @returns {Promise}
*/
const setupCertbotPlugins = () => {
return certificateModel
.query()
.where('is_deleted', 0)
.andWhere('provider', 'letsencrypt')
.then((certificates) => {
if (certificates && certificates.length) {
let plugins = [];
let promises = [];
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 + '\'; }';
promises.push(utils.exec(credentials_cmd));
}
});
if (plugins.length) {
const install_cmd = 'pip install ' + plugins.join(' ');
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(() => {
logger.info('Added Certbot plugins ' + plugins.join(', '));
});
}
}
});
};
/**
* Starts a timer to call run the logrotation binary every two days
* @returns {Promise}
*/
const setupLogrotation = () => {
const intervalTimeout = 1000 * 60 * 60 * 24 * 2; // 2 days
const runLogrotate = async () => {
try {
await utils.exec('logrotate /etc/logrotate.d/nginx-proxy-manager');
logger.info('Logrotate completed.');
} catch (e) { logger.warn(e); }
};
logger.info('Logrotate Timer initialized');
setInterval(runLogrotate, intervalTimeout);
// And do this now as well
return runLogrotate();
};
module.exports = function () { module.exports = function () {
return setupJwt() return setupJwt()
.then(setupDefaultUser) .then(setupDefaultUser)
.then(setupDefaultSettings) .then(setupDefaultSettings);
.then(setupCertbotPlugins)
.then(setupLogrotation);
}; };

View File

@ -1,8 +1,8 @@
{% if certificate and certificate_id > 0 -%} {% if certificate and certificate_id > 0 -%}
{% if ssl_forced == 1 or ssl_forced == true %} {% if ssl_forced == 1 or ssl_forced == true %}
{% if hsts_enabled == 1 or hsts_enabled == true %} {% if hsts_enabled == 1 or hsts_enabled == true %}
# HSTS (ngx_http_headers_module is required) (63072000 seconds = 2 years) # HSTS (ngx_http_headers_module is required) (31536000 seconds = 1 year)
add_header Strict-Transport-Security "max-age=63072000;{% if hsts_subdomains == 1 or hsts_subdomains == true -%} includeSubDomains;{% endif %} preload" always; add_header Strict-Transport-Security "max-age=31536000;{% if hsts_subdomains == 1 or hsts_subdomains == true -%} includeSubDomains;{% endif %} preload" always;
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endif %} {% endif %}

View File

@ -7,7 +7,7 @@
{% if certificate -%} {% if certificate -%}
listen 443 ssl{% if http2_support %} http2{% endif %}; listen 443 ssl{% if http2_support %} http2{% endif %};
{% if ipv6 -%} {% if ipv6 -%}
listen [::]:443 ssl{% if http2_support %} http2{% endif %}; listen [::]:443;
{% else -%} {% else -%}
#listen [::]:443; #listen [::]:443;
{% endif %} {% endif %}

View File

@ -3,43 +3,7 @@
proxy_set_header X-Forwarded-Scheme $scheme; proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass {{ forward_scheme }}://{{ forward_host }}:{{ forward_port }}{{ forward_path }}; proxy_pass {{ forward_scheme }}://{{ forward_host }}:{{ forward_port }}{{ forward_path }};
{% if access_list_id > 0 %}
{% if access_list.items.length > 0 %}
# Authorization
auth_basic "Authorization required";
auth_basic_user_file /data/access/{{ access_list_id }};
{{ access_list.passauth }}
{% endif %}
# Access Rules
{% for client in access_list.clients %}
{{- client.rule -}};
{% endfor %}deny all;
# Access checks must...
{% if access_list.satisfy %}
{{ access_list.satisfy }};
{% endif %}
{% endif %}
{% include "_assets.conf" %}
{% include "_exploits.conf" %}
{% include "_forced_ssl.conf" %}
{% include "_hsts.conf" %}
{% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %}
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;
{% endif %}
{{ advanced_config }} {{ advanced_config }}
} }

View File

@ -5,15 +5,14 @@ server {
{% include "_listen.conf" %} {% include "_listen.conf" %}
{% include "_certificates.conf" %} {% include "_certificates.conf" %}
{% include "_hsts.conf" %} {% include "_hsts.conf" %}
{% include "_forced_ssl.conf" %}
access_log /data/logs/dead-host-{{ id }}_access.log standard; access_log /data/logs/dead_host-{{ id }}.log standard;
error_log /data/logs/dead-host-{{ id }}_error.log warn;
{{ advanced_config }} {{ advanced_config }}
{% if use_default_location %} {% if use_default_location %}
location / { location / {
{% include "_forced_ssl.conf" %}
{% include "_hsts.conf" %} {% include "_hsts.conf" %}
return 404; return 404;
} }

View File

@ -6,18 +6,10 @@
{%- else %} {%- else %}
server { server {
listen 80 default; listen 80 default;
{% if ipv6 -%}
listen [::]:80 default;
{% else -%}
#listen [::]:80 default;
{% endif %}
server_name default-host.localhost; server_name default-host.localhost;
access_log /data/logs/default-host_access.log combined; access_log /data/logs/default_host.log combined;
error_log /data/logs/default-host_error.log warn;
{% include "_exploits.conf" %} {% include "_exploits.conf" %}
include conf.d/include/letsencrypt-acme-challenge.conf;
{%- if value == "404" %} {%- if value == "404" %}
location / { location / {
return 404; return 404;

View File

@ -8,8 +8,7 @@ server {
server_name {{ domain_names | join: " " }}; server_name {{ domain_names | join: " " }};
access_log /data/logs/letsencrypt-requests_access.log standard; access_log /data/logs/letsencrypt-requests.log standard;
error_log /data/logs/letsencrypt-requests_error.log warn;
include conf.d/include/letsencrypt-acme-challenge.conf; include conf.d/include/letsencrypt-acme-challenge.conf;

View File

@ -11,16 +11,8 @@ server {
{% include "_assets.conf" %} {% include "_assets.conf" %}
{% include "_exploits.conf" %} {% include "_exploits.conf" %}
{% include "_hsts.conf" %} {% include "_hsts.conf" %}
{% include "_forced_ssl.conf" %}
{% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %} access_log /data/logs/proxy_host-{{ id }}.log proxy;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;
{% endif %}
access_log /data/logs/proxy-host-{{ id }}_access.log proxy;
error_log /data/logs/proxy-host-{{ id }}_error.log warn;
{{ advanced_config }} {{ advanced_config }}
@ -51,6 +43,7 @@ proxy_http_version 1.1;
{% endif %} {% endif %}
{% include "_forced_ssl.conf" %}
{% include "_hsts.conf" %} {% include "_hsts.conf" %}
{% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %} {% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %}

View File

@ -7,21 +7,20 @@ server {
{% include "_assets.conf" %} {% include "_assets.conf" %}
{% include "_exploits.conf" %} {% include "_exploits.conf" %}
{% include "_hsts.conf" %} {% include "_hsts.conf" %}
{% include "_forced_ssl.conf" %}
access_log /data/logs/redirection-host-{{ id }}_access.log standard; access_log /data/logs/redirection_host-{{ id }}.log standard;
error_log /data/logs/redirection-host-{{ id }}_error.log warn;
{{ advanced_config }} {{ advanced_config }}
{% if use_default_location %} {% if use_default_location %}
location / { location / {
{% include "_forced_ssl.conf" %}
{% include "_hsts.conf" %} {% include "_hsts.conf" %}
{% if preserve_path == 1 or preserve_path == true %} {% if preserve_path == 1 or preserve_path == true %}
return {{ forward_http_code }} {{ forward_scheme }}://{{ forward_domain_name }}$request_uri; return 301 $scheme://{{ forward_domain_name }}$request_uri;
{% else %} {% else %}
return {{ forward_http_code }} {{ forward_scheme }}://{{ forward_domain_name }}; return 301 $scheme://{{ forward_domain_name }};
{% endif %} {% endif %}
} }
{% endif %} {% endif %}

View File

@ -12,7 +12,7 @@ server {
#listen [::]:{{ incoming_port }}; #listen [::]:{{ incoming_port }};
{% endif %} {% endif %}
proxy_pass {{ forwarding_host }}:{{ forwarding_port }}; proxy_pass {{ forward_ip }}:{{ forwarding_port }};
# Custom # Custom
include /data/nginx/custom/server_stream[.]conf; include /data/nginx/custom/server_stream[.]conf;
@ -27,7 +27,7 @@ server {
{% else -%} {% else -%}
#listen [::]:{{ incoming_port }} udp; #listen [::]:{{ incoming_port }} udp;
{% endif %} {% endif %}
proxy_pass {{ forwarding_host }}:{{ forwarding_port }}; proxy_pass {{ forward_ip }}:{{ forwarding_port }};
# Custom # Custom
include /data/nginx/custom/server_stream[.]conf; include /data/nginx/custom/server_stream[.]conf;

View File

@ -77,10 +77,10 @@ acorn@^7.1.1:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c"
integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w== integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==
ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.6: ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0:
version "6.12.6" version "6.12.3"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==
dependencies: dependencies:
fast-deep-equal "^3.1.1" fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0" fast-json-stable-stringify "^2.0.0"
@ -136,6 +136,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
"@types/color-name" "^1.1.1" "@types/color-name" "^1.1.1"
color-convert "^2.0.1" color-convert "^2.0.1"
ansi-styles@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178"
integrity sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=
anymatch@~3.1.1: anymatch@~3.1.1:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142"
@ -149,35 +154,6 @@ aproba@^1.0.3:
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
archiver-utils@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2"
integrity sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==
dependencies:
glob "^7.1.4"
graceful-fs "^4.2.0"
lazystream "^1.0.0"
lodash.defaults "^4.2.0"
lodash.difference "^4.5.0"
lodash.flatten "^4.4.0"
lodash.isplainobject "^4.0.6"
lodash.union "^4.6.0"
normalize-path "^3.0.0"
readable-stream "^2.0.0"
archiver@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/archiver/-/archiver-5.3.0.tgz#dd3e097624481741df626267564f7dd8640a45ba"
integrity sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==
dependencies:
archiver-utils "^2.1.0"
async "^3.2.0"
buffer-crc32 "^0.2.1"
readable-stream "^3.6.0"
readdir-glob "^1.0.0"
tar-stream "^2.2.0"
zip-stream "^4.1.0"
are-we-there-yet@~1.1.2: are-we-there-yet@~1.1.2:
version "1.1.5" version "1.1.5"
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21"
@ -245,11 +221,6 @@ astral-regex@^1.0.0:
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== 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==
atob@^2.1.2: atob@^2.1.2:
version "2.1.2" version "2.1.2"
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
@ -260,11 +231,6 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
base@^0.11.1: base@^0.11.1:
version "0.11.2" version "0.11.2"
resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
@ -301,15 +267,6 @@ binary-extensions@^2.0.0:
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9"
integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==
bl@^4.0.3:
version "4.1.0"
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
dependencies:
buffer "^5.5.0"
inherits "^2.0.4"
readable-stream "^3.4.0"
blueimp-md5@^2.16.0: blueimp-md5@^2.16.0:
version "2.17.0" version "2.17.0"
resolved "https://registry.yarnpkg.com/blueimp-md5/-/blueimp-md5-2.17.0.tgz#f4fcac088b115f7b4045f19f5da59e9d01b1bb96" resolved "https://registry.yarnpkg.com/blueimp-md5/-/blueimp-md5-2.17.0.tgz#f4fcac088b115f7b4045f19f5da59e9d01b1bb96"
@ -376,23 +333,15 @@ braces@~3.0.2:
dependencies: dependencies:
fill-range "^7.0.1" fill-range "^7.0.1"
buffer-crc32@^0.2.1, buffer-crc32@^0.2.13:
version "0.2.13"
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
buffer-equal-constant-time@1.0.1: buffer-equal-constant-time@1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
buffer@^5.5.0: buffer-writer@2.0.0:
version "5.7.1" version "2.0.0"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04"
integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==
dependencies:
base64-js "^1.3.1"
ieee754 "^1.1.13"
busboy@^0.3.1: busboy@^0.3.1:
version "0.3.1" version "0.3.1"
@ -454,6 +403,15 @@ camelcase@^5.0.0, camelcase@^5.3.1:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
chalk@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f"
integrity sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=
dependencies:
ansi-styles "~1.0.0"
has-color "~0.1.0"
strip-ansi "~0.1.0"
chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.2: chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.2:
version "2.4.2" version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@ -499,7 +457,7 @@ chokidar@^3.2.2:
optionalDependencies: optionalDependencies:
fsevents "~2.1.2" fsevents "~2.1.2"
chownr@^1.1.4: chownr@^1.1.1:
version "1.1.4" version "1.1.4"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
@ -604,16 +562,6 @@ component-emitter@^1.2.1:
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
compress-commons@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-4.1.1.tgz#df2a09a7ed17447642bad10a85cc9a19e5c42a7d"
integrity sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==
dependencies:
buffer-crc32 "^0.2.13"
crc32-stream "^4.0.2"
normalize-path "^3.0.0"
readable-stream "^3.6.0"
compressible@~2.0.16: compressible@~2.0.16:
version "2.0.18" version "2.0.18"
resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"
@ -695,22 +643,6 @@ core-util-is@~1.0.0:
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
crc-32@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208"
integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==
dependencies:
exit-on-epipe "~1.0.1"
printj "~1.1.0"
crc32-stream@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-4.0.2.tgz#c922ad22b38395abe9d3870f02fa8134ed709007"
integrity sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==
dependencies:
crc-32 "^1.2.0"
readable-stream "^3.4.0"
cross-spawn@^6.0.5: cross-spawn@^6.0.5:
version "6.0.5" version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
@ -839,6 +771,15 @@ dicer@0.3.0:
dependencies: dependencies:
streamsearch "0.1.2" streamsearch "0.1.2"
diskdb@^0.1.17:
version "0.1.17"
resolved "https://registry.yarnpkg.com/diskdb/-/diskdb-0.1.17.tgz#8abd095196b33b406791f1494b6b13b4422240c4"
integrity sha1-ir0JUZazO0BnkfFJS2sTtEIiQMQ=
dependencies:
chalk "^0.4.0"
merge "^1.1.3"
node-uuid "^1.4.1"
doctrine@^3.0.0: doctrine@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
@ -890,7 +831,7 @@ encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
end-of-stream@^1.1.0, end-of-stream@^1.4.1: end-of-stream@^1.1.0:
version "1.4.4" version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
@ -1040,11 +981,6 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
exit-on-epipe@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692"
integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==
expand-brackets@^2.1.4: expand-brackets@^2.1.4:
version "2.1.4" version "2.1.4"
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622"
@ -1301,12 +1237,7 @@ fresh@0.5.2:
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
fs-constants@^1.0.0: fs-minipass@^1.2.5:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
fs-minipass@^1.2.7:
version "1.2.7" version "1.2.7"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==
@ -1390,18 +1321,6 @@ glob@^7.1.3:
once "^1.3.0" once "^1.3.0"
path-is-absolute "^1.0.0" path-is-absolute "^1.0.0"
glob@^7.1.4:
version "7.1.7"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90"
integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
global-dirs@^2.0.1: global-dirs@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.0.1.tgz#acdf3bb6685bcd55cb35e8a052266569e9469201" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.0.1.tgz#acdf3bb6685bcd55cb35e8a052266569e9469201"
@ -1458,11 +1377,6 @@ graceful-fs@^4.1.15, graceful-fs@^4.1.2:
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
graceful-fs@^4.2.0:
version "4.2.8"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
gravatar@^1.8.0: gravatar@^1.8.0:
version "1.8.1" version "1.8.1"
resolved "https://registry.yarnpkg.com/gravatar/-/gravatar-1.8.1.tgz#743bbdf3185c3433172e00e0e6ff5f6b30c58997" resolved "https://registry.yarnpkg.com/gravatar/-/gravatar-1.8.1.tgz#743bbdf3185c3433172e00e0e6ff5f6b30c58997"
@ -1473,6 +1387,11 @@ gravatar@^1.8.0:
querystring "0.2.0" querystring "0.2.0"
yargs "^15.4.1" yargs "^15.4.1"
has-color@~0.1.0:
version "0.1.7"
resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f"
integrity sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=
has-flag@^3.0.0: has-flag@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
@ -1531,6 +1450,11 @@ homedir-polyfill@^1.0.1:
dependencies: dependencies:
parse-passwd "^1.0.0" parse-passwd "^1.0.0"
html-entities@^1.2.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.3.1.tgz#fb9a1a4b5b14c5daba82d3e34c6ae4fe701a0e44"
integrity sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==
http-cache-semantics@^4.0.0: http-cache-semantics@^4.0.0:
version "4.1.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
@ -1558,6 +1482,11 @@ http-errors@~1.7.2:
statuses ">= 1.5.0 < 2" statuses ">= 1.5.0 < 2"
toidentifier "1.0.0" toidentifier "1.0.0"
iconv-lite@0.2.11:
version "0.2.11"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.2.11.tgz#1ce60a3a57864a292d1321ff4609ca4bb965adc8"
integrity sha1-HOYKOleGSiktEyH/RgnKS7llrcg=
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
version "0.4.24" version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@ -1565,11 +1494,6 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
dependencies: dependencies:
safer-buffer ">= 2.1.2 < 3" safer-buffer ">= 2.1.2 < 3"
ieee754@^1.1.13:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
ignore-by-default@^1.0.1: ignore-by-default@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
@ -1613,7 +1537,7 @@ inflight@^1.0.4:
once "^1.3.0" once "^1.3.0"
wrappy "1" wrappy "1"
inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4: inherits@2, inherits@2.0.4, inherits@~2.0.3, inherits@~2.0.4:
version "2.0.4" version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@ -1624,9 +1548,9 @@ inherits@2.0.3:
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: ini@^1.3.4, ini@^1.3.5, ini@~1.3.0:
version "1.3.8" version "1.3.5"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
inquirer@^7.0.0: inquirer@^7.0.0:
version "7.3.3" version "7.3.3"
@ -2013,13 +1937,6 @@ latest-version@^5.0.0:
dependencies: dependencies:
package-json "^6.3.0" package-json "^6.3.0"
lazystream@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4"
integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=
dependencies:
readable-stream "^2.0.5"
levn@^0.3.0, levn@~0.3.0: levn@^0.3.0, levn@~0.3.0:
version "0.3.0" version "0.3.0"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
@ -2072,21 +1989,6 @@ locate-path@^5.0.0:
dependencies: dependencies:
p-locate "^4.1.0" p-locate "^4.1.0"
lodash.defaults@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=
lodash.difference@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c"
integrity sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=
lodash.flatten@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
lodash.includes@^4.3.0: lodash.includes@^4.3.0:
version "4.3.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
@ -2122,15 +2024,10 @@ lodash.once@^4.0.0:
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
lodash.union@^4.6.0: lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19:
version "4.6.0" version "4.17.19"
resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg= integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
version "1.0.1" version "1.0.1"
@ -2178,6 +2075,11 @@ merge-descriptors@1.0.1:
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
merge@^1.1.3:
version "1.2.1"
resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145"
integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==
methods@~1.1.2: methods@~1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
@ -2241,7 +2143,7 @@ minimist@^1.2.0, minimist@^1.2.5:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
minipass@^2.6.0, minipass@^2.9.0: minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0:
version "2.9.0" version "2.9.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6"
integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==
@ -2249,7 +2151,7 @@ minipass@^2.6.0, minipass@^2.9.0:
safe-buffer "^5.1.2" safe-buffer "^5.1.2"
yallist "^3.0.0" yallist "^3.0.0"
minizlib@^1.3.3: minizlib@^1.2.1:
version "1.3.3" version "1.3.3"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d"
integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==
@ -2264,17 +2166,17 @@ mixin-deep@^1.2.0:
for-in "^1.0.2" for-in "^1.0.2"
is-extendable "^1.0.1" is-extendable "^1.0.1"
mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5: mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3:
version "0.5.5" version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
dependencies: dependencies:
minimist "^1.2.5" minimist "^1.2.5"
moment@^2.29.4: moment@^2.24.0:
version "2.29.4" version "2.27.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d"
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==
ms@2.0.0: ms@2.0.0:
version "2.0.0" version "2.0.0"
@ -2396,6 +2298,11 @@ node-rsa@^1.0.8:
dependencies: dependencies:
asn1 "^0.2.4" asn1 "^0.2.4"
node-uuid@^1.4.1:
version "1.4.8"
resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907"
integrity sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=
nodemon@^2.0.2: nodemon@^2.0.2:
version "2.0.4" version "2.0.4"
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.4.tgz#55b09319eb488d6394aa9818148c0c2d1c04c416" resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.4.tgz#55b09319eb488d6394aa9818148c0c2d1c04c416"
@ -2433,9 +2340,9 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
normalize-url@^4.1.0: normalize-url@^4.1.0:
version "4.5.1" version "4.5.0"
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==
npm-bundled@^1.0.1: npm-bundled@^1.0.1:
version "1.1.1" version "1.1.1"
@ -2519,12 +2426,12 @@ object.pick@^1.2.0, object.pick@^1.3.0:
dependencies: dependencies:
isobject "^3.0.1" isobject "^3.0.1"
objection@^2.2.16: objection@^2.1.3:
version "2.2.16" version "2.2.2"
resolved "https://registry.yarnpkg.com/objection/-/objection-2.2.16.tgz#552ec6d625a7f80d6e204fc63732cbd3fc56f31c" resolved "https://registry.yarnpkg.com/objection/-/objection-2.2.2.tgz#1a3c9010270e3677940d2bc91aeaeb3c0f103800"
integrity sha512-sq8erZdxW5ruPUK6tVvwDxyO16U49XAn/BmOm2zaNhNA2phOPCe2/7+R70nDEF1SFrgJOrwDu/PtoxybuJxnjQ== integrity sha512-+1Ap7u9NQRochzDW5/BggUlKi94JfZGTJwQJuNXo8DwmAb8czEirvxcWBcX91/MmQq0BQUJjM4RPSiZhnkkWQw==
dependencies: dependencies:
ajv "^6.12.6" ajv "^6.12.0"
db-errors "^0.2.3" db-errors "^0.2.3"
on-finished@~2.3.0: on-finished@~2.3.0:
@ -2636,6 +2543,11 @@ package-json@^6.3.0:
registry-url "^5.0.0" registry-url "^5.0.0"
semver "^6.2.0" semver "^6.2.0"
packet-reader@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74"
integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==
parent-module@^1.0.0: parent-module@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
@ -2696,9 +2608,9 @@ path-key@^2.0.1:
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
path-parse@^1.0.6: path-parse@^1.0.6:
version "1.0.7" version "1.0.6"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
path-root-regex@^0.1.0: path-root-regex@^0.1.0:
version "0.1.2" version "0.1.2"
@ -2725,11 +2637,63 @@ path@^0.12.7:
process "^0.11.1" process "^0.11.1"
util "^0.10.3" util "^0.10.3"
pg-connection-string@0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-0.1.3.tgz#da1847b20940e42ee1492beaf65d49d91b245df7"
integrity sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=
pg-connection-string@2.1.0: pg-connection-string@2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.1.0.tgz#e07258f280476540b24818ebb5dca29e101ca502" resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.1.0.tgz#e07258f280476540b24818ebb5dca29e101ca502"
integrity sha512-bhlV7Eq09JrRIvo1eKngpwuqKtJnNhZdpdOlvrPrA4dxqXPjxSrbNrfnIDmTpwMyRszrcV4kU5ZA4mMsQUrjdg== integrity sha512-bhlV7Eq09JrRIvo1eKngpwuqKtJnNhZdpdOlvrPrA4dxqXPjxSrbNrfnIDmTpwMyRszrcV4kU5ZA4mMsQUrjdg==
pg-int8@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c"
integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==
pg-packet-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pg-packet-stream/-/pg-packet-stream-1.1.0.tgz#e45c3ae678b901a2873af1e17b92d787962ef914"
integrity sha512-kRBH0tDIW/8lfnnOyTwKD23ygJ/kexQVXZs7gEyBljw4FYqimZFxnMMx50ndZ8In77QgfGuItS5LLclC2TtjYg==
pg-pool@^2.0.10:
version "2.0.10"
resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-2.0.10.tgz#842ee23b04e86824ce9d786430f8365082d81c4a"
integrity sha512-qdwzY92bHf3nwzIUcj+zJ0Qo5lpG/YxchahxIN8+ZVmXqkahKXsnl2aiJPHLYN9o5mB/leG+Xh6XKxtP7e0sjg==
pg-types@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3"
integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==
dependencies:
pg-int8 "1.0.1"
postgres-array "~2.0.0"
postgres-bytea "~1.0.0"
postgres-date "~1.0.4"
postgres-interval "^1.1.0"
pg@^7.12.1:
version "7.18.2"
resolved "https://registry.yarnpkg.com/pg/-/pg-7.18.2.tgz#4e219f05a00aff4db6aab1ba02f28ffa4513b0bb"
integrity sha512-Mvt0dGYMwvEADNKy5PMQGlzPudKcKKzJds/VbOeZJpb6f/pI3mmoXX0JksPgI3l3JPP/2Apq7F36O63J7mgveA==
dependencies:
buffer-writer "2.0.0"
packet-reader "1.0.0"
pg-connection-string "0.1.3"
pg-packet-stream "^1.1.0"
pg-pool "^2.0.10"
pg-types "^2.1.0"
pgpass "1.x"
semver "4.3.2"
pgpass@1.x:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.2.tgz#2a7bb41b6065b67907e91da1b07c1847c877b306"
integrity sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=
dependencies:
split "^1.0.0"
picomatch@^2.0.4, picomatch@^2.2.1: picomatch@^2.0.4, picomatch@^2.2.1:
version "2.2.2" version "2.2.2"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
@ -2753,6 +2717,28 @@ posix-character-classes@^0.1.0:
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
postgres-array@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e"
integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==
postgres-bytea@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35"
integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=
postgres-date@~1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.6.tgz#4925e8085b30c2ba1a06ac91b9a3473954a2ce2d"
integrity sha512-o2a4gxeFcox+CgB3Ig/kNHBP23PiEXHCXx7pcIIsvzoNz4qv+lKTyiSkjOXIMNUl12MO/mOYl2K6wR9X5K6Plg==
postgres-interval@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695"
integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==
dependencies:
xtend "^4.0.0"
prelude-ls@~1.1.2: prelude-ls@~1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
@ -2768,11 +2754,6 @@ prettier@^2.0.4:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4"
integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg== integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==
printj@~1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222"
integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==
process-nextick-args@~2.0.0: process-nextick-args@~2.0.0:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@ -2821,6 +2802,11 @@ pupa@^2.0.1:
dependencies: dependencies:
escape-goat "^2.0.0" escape-goat "^2.0.0"
qs@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-1.2.0.tgz#ed079be28682147e6fd9a34cc2b0c1e0ec6453ee"
integrity sha1-7Qeb4oaCFH5v2aNMwrDB4OxkU+4=
qs@6.7.0: qs@6.7.0:
version "6.7.0" version "6.7.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
@ -2856,7 +2842,7 @@ rc@^1.2.7, rc@^1.2.8:
minimist "^1.2.0" minimist "^1.2.0"
strip-json-comments "~2.0.1" strip-json-comments "~2.0.1"
readable-stream@2.3.7, readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.0.6: readable-stream@2.3.7, readable-stream@^2.0.6:
version "2.3.7" version "2.3.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
@ -2869,22 +2855,6 @@ readable-stream@2.3.7, readable-stream@^2.0.0, readable-stream@^2.0.5, readable-
string_decoder "~1.1.1" string_decoder "~1.1.1"
util-deprecate "~1.0.1" util-deprecate "~1.0.1"
readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
dependencies:
inherits "^2.0.3"
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
readdir-glob@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/readdir-glob/-/readdir-glob-1.1.1.tgz#f0e10bb7bf7bfa7e0add8baffdc54c3f7dbee6c4"
integrity sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==
dependencies:
minimatch "^3.0.4"
readdirp@~3.4.0: readdirp@~3.4.0:
version "3.4.0" version "3.4.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada"
@ -2978,6 +2948,16 @@ responselike@^1.0.2:
dependencies: dependencies:
lowercase-keys "^1.0.0" lowercase-keys "^1.0.0"
restler@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/restler/-/restler-3.4.0.tgz#741ec0b3d16b949feea2813d0c3c68529e888d9b"
integrity sha1-dB7As9FrlJ/uooE9DDxoUp6IjZs=
dependencies:
iconv-lite "0.2.11"
qs "1.2.0"
xml2js "0.4.0"
yaml "0.2.3"
restore-cursor@^3.1.0: restore-cursor@^3.1.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e"
@ -3022,7 +3002,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@^5.2.1, safe-buffer@~5.2.0: safe-buffer@^5.0.1, safe-buffer@^5.1.2:
version "5.2.1" version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
@ -3039,6 +3019,11 @@ safe-regex@^1.1.0:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
sax@0.5.x:
version "0.5.8"
resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1"
integrity sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=
sax@^1.2.4: sax@^1.2.4:
version "1.2.4" version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
@ -3051,6 +3036,11 @@ semver-diff@^3.1.1:
dependencies: dependencies:
semver "^6.3.0" semver "^6.3.0"
semver@4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.2.tgz#c7a07158a80bedd052355b770d82d6640f803be7"
integrity sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=
semver@^5.3.0, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: semver@^5.3.0, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1:
version "5.7.1" version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
@ -3203,6 +3193,13 @@ split-string@^3.0.1, split-string@^3.0.2:
dependencies: dependencies:
extend-shallow "^3.0.0" extend-shallow "^3.0.0"
split@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==
dependencies:
through "2"
sprintf-js@~1.0.2: sprintf-js@~1.0.2:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
@ -3274,13 +3271,6 @@ string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0:
is-fullwidth-code-point "^3.0.0" is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.0" strip-ansi "^6.0.0"
string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
dependencies:
safe-buffer "~5.2.0"
string_decoder@~1.1.1: string_decoder@~1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
@ -3316,6 +3306,11 @@ strip-ansi@^6.0.0:
dependencies: dependencies:
ansi-regex "^5.0.0" ansi-regex "^5.0.0"
strip-ansi@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991"
integrity sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=
strip-bom@^3.0.0: strip-bom@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
@ -3355,29 +3350,18 @@ table@^5.2.3:
slice-ansi "^2.1.0" slice-ansi "^2.1.0"
string-width "^3.0.0" string-width "^3.0.0"
tar-stream@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
dependencies:
bl "^4.0.3"
end-of-stream "^1.4.1"
fs-constants "^1.0.0"
inherits "^2.0.3"
readable-stream "^3.1.1"
tar@^4, tar@^4.4.2: tar@^4, tar@^4.4.2:
version "4.4.19" version "4.4.13"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
dependencies: dependencies:
chownr "^1.1.4" chownr "^1.1.1"
fs-minipass "^1.2.7" fs-minipass "^1.2.5"
minipass "^2.9.0" minipass "^2.8.6"
minizlib "^1.3.3" minizlib "^1.2.1"
mkdirp "^0.5.5" mkdirp "^0.5.0"
safe-buffer "^5.2.1" safe-buffer "^5.1.2"
yallist "^3.1.1" yallist "^3.0.3"
tarn@^2.0.0: tarn@^2.0.0:
version "2.0.0" version "2.0.0"
@ -3410,7 +3394,7 @@ text-table@^0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
through@^2.3.6: through@2, through@^2.3.6:
version "2.3.8" version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
@ -3542,6 +3526,11 @@ unique-string@^2.0.0:
dependencies: dependencies:
crypto-random-string "^2.0.0" crypto-random-string "^2.0.0"
unix-timestamp@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/unix-timestamp/-/unix-timestamp-0.2.0.tgz#e1cdc2808df6327d27e635d9351e72815288733e"
integrity sha1-4c3CgI32Mn0n5jXZNR5ygVKIcz4=
unpipe@1.0.0, unpipe@~1.0.0: unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
@ -3598,7 +3587,7 @@ use@^3.1.0:
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==
util-deprecate@^1.0.1, util-deprecate@~1.0.1: util-deprecate@~1.0.1:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
@ -3709,16 +3698,39 @@ xdg-basedir@^4.0.0:
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==
y18n@^4.0.0: xml2js@0.4.0:
version "4.0.1" version "0.4.0"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.0.tgz#124fc4114b4129c810800ecb2ac86cf25462cb9a"
integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== integrity sha1-Ek/EEUtBKcgQgA7LKshs8lRiy5o=
dependencies:
sax "0.5.x"
xmlbuilder ">=0.4.2"
yallist@^3.0.0, yallist@^3.1.1: xmlbuilder@>=0.4.2:
version "15.1.1"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz#9dcdce49eea66d8d10b42cae94a79c3c8d0c2ec5"
integrity sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==
xtend@^4.0.0:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
y18n@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
yallist@^3.0.0, yallist@^3.0.3:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
yaml@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-0.2.3.tgz#b5450e92e76ef36b5dd24e3660091ebaeef3e5c7"
integrity sha1-tUUOkudu82td0k42YAkeuu7z5cc=
yargs-parser@^18.1.2: yargs-parser@^18.1.2:
version "18.1.3" version "18.1.3"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
@ -3743,12 +3755,3 @@ yargs@^15.4.1:
which-module "^2.0.0" which-module "^2.0.0"
y18n "^4.0.0" y18n "^4.0.0"
yargs-parser "^18.1.2" yargs-parser "^18.1.2"
zip-stream@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-4.1.0.tgz#51dd326571544e36aa3f756430b313576dc8fc79"
integrity sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==
dependencies:
archiver-utils "^2.1.0"
compress-commons "^4.1.0"
readable-stream "^3.6.0"

View File

@ -1,14 +0,0 @@
rules:
# If the efficiency is measured below X%, mark as failed.
# Expressed as a ratio between 0-1.
lowestEfficiency: 0.99
# If the amount of wasted space is at least X or larger than X, mark as failed.
# Expressed in B, KB, MB, and GB.
highestWastedBytes: 15MB
# If the amount of wasted space makes up for X% or more of the image, mark as failed.
# Note: the base image layer is NOT included in the total image size.
# Expressed as a ratio between 0-1; fails if the threshold is met or crossed.
highestUserWastedPercent: 0.02

View File

@ -3,61 +3,46 @@
# This file assumes that the frontend has been built using ./scripts/frontend-build # This file assumes that the frontend has been built using ./scripts/frontend-build
FROM nginxproxymanager/nginx-full:certbot-node FROM --platform=${TARGETPLATFORM:-linux/amd64} jc21/alpine-nginx-full:node
ARG TARGETPLATFORM ARG TARGETPLATFORM
ARG BUILDPLATFORM
ARG BUILD_VERSION ARG BUILD_VERSION
ARG BUILD_COMMIT ARG BUILD_COMMIT
ARG BUILD_DATE ARG BUILD_DATE
ENV SUPPRESS_NO_CONFIG_WARNING=1 \ ENV SUPPRESS_NO_CONFIG_WARNING=1
S6_FIX_ATTRS_HIDDEN=1 \ ENV S6_FIX_ATTRS_HIDDEN=1
S6_BEHAVIOUR_IF_STAGE2_FAILS=1 \ ENV NODE_ENV=production
NODE_ENV=production \
NPM_BUILD_VERSION="${BUILD_VERSION}" \
NPM_BUILD_COMMIT="${BUILD_COMMIT}" \
NPM_BUILD_DATE="${BUILD_DATE}"
RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \ RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
&& apt-get update \ && apk update \
&& apt-get install -y --no-install-recommends jq logrotate \ && apk add python3 certbot jq \
&& apt-get clean \ && python3 -m ensurepip \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/cache/apk/*
ENV NPM_BUILD_VERSION="${BUILD_VERSION}" NPM_BUILD_COMMIT="${BUILD_COMMIT}" NPM_BUILD_DATE="${BUILD_DATE}"
# s6 overlay # s6 overlay
COPY scripts/install-s6 /tmp/install-s6 COPY scripts/install-s6 /tmp/install-s6
RUN /tmp/install-s6 "${TARGETPLATFORM}" && rm -f /tmp/install-s6 RUN /tmp/install-s6 "${TARGETPLATFORM}" && rm -f /tmp/install-s6
EXPOSE 80 81 443 EXPOSE 80
EXPOSE 81
EXPOSE 443
COPY backend /app COPY docker/rootfs /
COPY frontend/dist /app/frontend ADD backend /app
COPY global /app/global ADD frontend/dist /app/frontend
COPY global /app/global
WORKDIR /app WORKDIR /app
RUN yarn install RUN yarn install
# add late to limit cache-busting by modifications
COPY docker/rootfs /
# Remove frontend service not required for prod, dev nginx config as well # Remove frontend service not required for prod, dev nginx config as well
RUN rm -rf /etc/services.d/frontend /etc/nginx/conf.d/dev.conf RUN rm -rf /etc/services.d/frontend RUN rm -f /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" ] VOLUME [ "/data", "/etc/letsencrypt" ]
ENTRYPOINT [ "/init" ] CMD [ "/init" ]
LABEL org.label-schema.schema-version="1.0" \ HEALTHCHECK --interval=5s --timeout=3s CMD /bin/check-health
org.label-schema.license="MIT" \
org.label-schema.name="nginx-proxy-manager" \
org.label-schema.description="Docker container for managing Nginx proxy hosts with a simple, powerful interface " \
org.label-schema.url="https://github.com/jc21/nginx-proxy-manager" \
org.label-schema.vcs-url="https://github.com/jc21/nginx-proxy-manager.git" \
org.label-schema.cmd="docker run --rm -ti jc21/nginx-proxy-manager:latest"

View File

@ -1,15 +1,15 @@
FROM nginxproxymanager/nginx-full:certbot-node FROM jc21/alpine-nginx-full:node
LABEL maintainer="Jamie Curnow <jc@jc21.com>" LABEL maintainer="Jamie Curnow <jc@jc21.com>"
ENV S6_LOGGING=0 \ ENV S6_LOGGING=0
SUPPRESS_NO_CONFIG_WARNING=1 \ ENV SUPPRESS_NO_CONFIG_WARNING=1
S6_FIX_ATTRS_HIDDEN=1 ENV S6_FIX_ATTRS_HIDDEN=1
RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \ RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
&& apt-get update \ && apk update \
&& apt-get install -y certbot jq python3-pip logrotate \ && apk add python3 certbot jq \
&& apt-get clean \ && python3 -m ensurepip \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/cache/apk/*
# Task # Task
RUN cd /usr \ RUN cd /usr \
@ -18,12 +18,15 @@ RUN cd /usr \
COPY rootfs / COPY rootfs /
RUN rm -f /etc/nginx/conf.d/production.conf RUN rm -f /etc/nginx/conf.d/production.conf
RUN chmod 644 /etc/logrotate.d/nginx-proxy-manager
# s6 overlay # s6 overlay
RUN curl -L -o /tmp/s6-overlay-amd64.tar.gz "https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-amd64.tar.gz" \ RUN curl -L -o /tmp/s6-overlay-amd64.tar.gz "https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-amd64.tar.gz" \
&& tar -xzf /tmp/s6-overlay-amd64.tar.gz -C / && tar -xzf /tmp/s6-overlay-amd64.tar.gz -C /
EXPOSE 80 81 443 EXPOSE 80
ENTRYPOINT [ "/init" ] EXPOSE 81
EXPOSE 443
CMD [ "/init" ]
HEALTHCHECK --interval=5s --timeout=3s CMD /bin/check-health

View File

@ -5,42 +5,30 @@ services:
fullstack-mysql: fullstack-mysql:
image: ${IMAGE}:ci-${BUILD_NUMBER} image: ${IMAGE}:ci-${BUILD_NUMBER}
environment: environment:
NODE_ENV: "development" - NODE_ENV=development
FORCE_COLOR: 1 - FORCE_COLOR=1
DB_MYSQL_HOST: "db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
DB_MYSQL_PASSWORD: "npm"
DB_MYSQL_NAME: "npm"
volumes: volumes:
- npm_data:/data - npm_data:/data
- ../.jenkins/config-mysql.json:/app/config/development.json
expose: expose:
- 81 - 81
- 80 - 80
- 443 - 443
depends_on: depends_on:
- db - db
healthcheck:
test: ["CMD", "/bin/check-health"]
interval: 10s
timeout: 3s
fullstack-sqlite: fullstack-sqlite:
image: ${IMAGE}:ci-${BUILD_NUMBER} image: ${IMAGE}:ci-${BUILD_NUMBER}
environment: environment:
NODE_ENV: "development" - NODE_ENV=development
FORCE_COLOR: 1 - FORCE_COLOR=1
DB_SQLITE_FILE: "/data/database.sqlite"
volumes: volumes:
- npm_data:/data - npm_data:/data
- ../.jenkins/config-sqlite.json:/app/config/development.json
expose: expose:
- 81 - 81
- 80 - 80
- 443 - 443
healthcheck:
test: ["CMD", "/bin/check-health"]
interval: 10s
timeout: 3s
db: db:
image: jc21/mariadb-aria image: jc21/mariadb-aria
@ -55,8 +43,8 @@ services:
cypress-mysql: cypress-mysql:
image: ${IMAGE}-cypress:ci-${BUILD_NUMBER} image: ${IMAGE}-cypress:ci-${BUILD_NUMBER}
build: build:
context: ../test/ context: ../
dockerfile: cypress/Dockerfile dockerfile: test/cypress/Dockerfile
environment: environment:
CYPRESS_baseUrl: "http://fullstack-mysql:81" CYPRESS_baseUrl: "http://fullstack-mysql:81"
volumes: volumes:
@ -66,8 +54,8 @@ services:
cypress-sqlite: cypress-sqlite:
image: ${IMAGE}-cypress:ci-${BUILD_NUMBER} image: ${IMAGE}-cypress:ci-${BUILD_NUMBER}
build: build:
context: ../test/ context: ../
dockerfile: cypress/Dockerfile dockerfile: test/cypress/Dockerfile
environment: environment:
CYPRESS_baseUrl: "http://fullstack-sqlite:81" CYPRESS_baseUrl: "http://fullstack-sqlite:81"
volumes: volumes:

View File

@ -1,9 +1,9 @@
# WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production. # WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production.
version: "3.5" version: "3"
services: services:
npm: npm:
image: nginxproxymanager:dev image: nginxproxymanager:dev
container_name: npm_core
build: build:
context: ./ context: ./
dockerfile: ./dev/Dockerfile dockerfile: ./dev/Dockerfile
@ -14,16 +14,10 @@ services:
networks: networks:
- nginx_proxy_manager - nginx_proxy_manager
environment: environment:
NODE_ENV: "development" - NODE_ENV=development
FORCE_COLOR: 1 - FORCE_COLOR=1
DEVELOPMENT: "true" - DEVELOPMENT=true
DB_MYSQL_HOST: "db" #- DISABLE_IPV6=true
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
DB_MYSQL_PASSWORD: "npm"
DB_MYSQL_NAME: "npm"
# DB_SQLITE_FILE: "/data/database.sqlite"
# DISABLE_IPV6: "true"
volumes: volumes:
- npm_data:/data - npm_data:/data
- le_data:/etc/letsencrypt - le_data:/etc/letsencrypt
@ -36,9 +30,6 @@ services:
db: db:
image: jc21/mariadb-aria image: jc21/mariadb-aria
container_name: npm_db
ports:
- 33306:3306
networks: networks:
- nginx_proxy_manager - nginx_proxy_manager
environment: environment:
@ -49,14 +40,22 @@ services:
volumes: volumes:
- db_data:/var/lib/mysql - db_data:/var/lib/mysql
swagger:
image: 'swaggerapi/swagger-ui:latest'
ports:
- 3001:80
networks:
- nginx_proxy_manager
environment:
URL: "http://127.0.0.1:3081/api/schema"
PORT: '80'
depends_on:
- npm
volumes: volumes:
npm_data: npm_data:
name: npm_core_data
le_data: le_data:
name: npm_le_data
db_data: db_data:
name: npm_db_data
networks: networks:
nginx_proxy_manager: nginx_proxy_manager:
name: npm_network

View File

@ -1,3 +1,2 @@
* *
!.gitignore !.gitignore
!*.sh

View File

@ -1,7 +0,0 @@
#!/usr/bin/with-contenv bash
set -e
mkdir -p /data/logs
echo "Changing ownership of /data/logs to $(id -u):$(id -g)"
chown -R "$(id -u):$(id -g)" /data/logs

View File

@ -1,29 +0,0 @@
#!/usr/bin/with-contenv bash
# ref: https://github.com/linuxserver/docker-baseimage-alpine/blob/master/root/etc/cont-init.d/01-envfile
# in s6, environmental variables are written as text files for s6 to monitor
# search through full-path filenames for files ending in "__FILE"
for FILENAME in $(find /var/run/s6/container_environment/ | grep "__FILE$"); do
echo "[secret-init] Evaluating ${FILENAME##*/} ..."
# set SECRETFILE to the contents of the full-path textfile
SECRETFILE=$(cat ${FILENAME})
# SECRETFILE=${FILENAME}
# echo "[secret-init] Set SECRETFILE to ${SECRETFILE}" # DEBUG - rm for prod!
# if SECRETFILE exists / is not null
if [[ -f ${SECRETFILE} ]]; then
# strip the appended "__FILE" from environmental variable name ...
STRIPFILE=$(echo ${FILENAME} | sed "s/__FILE//g")
# echo "[secret-init] Set STRIPFILE to ${STRIPFILE}" # DEBUG - rm for prod!
# ... and set value to contents of secretfile
# since s6 uses text files, this is effectively "export ..."
printf $(cat ${SECRETFILE}) > ${STRIPFILE}
# echo "[secret-init] Set ${STRIPFILE##*/} to $(cat ${STRIPFILE})" # DEBUG - rm for prod!"
echo "[secret-init] Success! ${STRIPFILE##*/} set from ${FILENAME##*/}"
else
echo "[secret-init] cannot find secret in ${FILENAME}"
fi
done

View File

@ -1,6 +1,4 @@
text = True text = True
non-interactive = True non-interactive = True
authenticator = webroot
webroot-path = /data/letsencrypt-acme-challenge webroot-path = /data/letsencrypt-acme-challenge
key-type = ecdsa
elliptic-curve = secp384r1
preferred-chain = ISRG Root X1

View File

@ -1,25 +0,0 @@
/data/logs/*_access.log /data/logs/*/access.log {
create 0644 root root
weekly
rotate 4
missingok
notifempty
compress
sharedscripts
postrotate
/bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
endscript
}
/data/logs/*_error.log /data/logs/*/error.log {
create 0644 root root
weekly
rotate 10
missingok
notifempty
compress
sharedscripts
postrotate
/bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
endscript
}

View File

@ -8,11 +8,10 @@ server {
set $port "80"; set $port "80";
server_name localhost-nginx-proxy-manager; server_name localhost-nginx-proxy-manager;
access_log /data/logs/fallback_access.log standard; access_log /data/logs/default.log standard;
error_log /data/logs/fallback_error.log warn; error_log /dev/null crit;
include conf.d/include/assets.conf; include conf.d/include/assets.conf;
include conf.d/include/block-exploits.conf; include conf.d/include/block-exploits.conf;
include conf.d/include/letsencrypt-acme-challenge.conf;
location / { location / {
index index.html; index index.html;
@ -30,7 +29,7 @@ server {
set $port "443"; set $port "443";
server_name localhost; server_name localhost;
access_log /data/logs/fallback_access.log standard; access_log /data/logs/default.log standard;
error_log /dev/null crit; error_log /dev/null crit;
ssl_certificate /data/nginx/dummycert.pem; ssl_certificate /data/nginx/dummycert.pem;
ssl_certificate_key /data/nginx/dummykey.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; if_modified_since off;
# use the public cache # use the public cache

View File

@ -1,2 +1,196 @@
# This should be left blank is it is populated programatically
# by the application backend. set_real_ip_from 144.220.0.0/16;
set_real_ip_from 52.124.128.0/17;
set_real_ip_from 54.230.0.0/16;
set_real_ip_from 54.239.128.0/18;
set_real_ip_from 52.82.128.0/19;
set_real_ip_from 99.84.0.0/16;
set_real_ip_from 204.246.172.0/24;
set_real_ip_from 205.251.192.0/19;
set_real_ip_from 54.239.192.0/19;
set_real_ip_from 70.132.0.0/18;
set_real_ip_from 13.32.0.0/15;
set_real_ip_from 13.224.0.0/14;
set_real_ip_from 13.35.0.0/16;
set_real_ip_from 204.246.164.0/22;
set_real_ip_from 204.246.168.0/22;
set_real_ip_from 71.152.0.0/17;
set_real_ip_from 216.137.32.0/19;
set_real_ip_from 205.251.249.0/24;
set_real_ip_from 99.86.0.0/16;
set_real_ip_from 52.46.0.0/18;
set_real_ip_from 52.84.0.0/15;
set_real_ip_from 204.246.173.0/24;
set_real_ip_from 130.176.0.0/16;
set_real_ip_from 64.252.64.0/18;
set_real_ip_from 204.246.174.0/23;
set_real_ip_from 64.252.128.0/18;
set_real_ip_from 205.251.254.0/24;
set_real_ip_from 143.204.0.0/16;
set_real_ip_from 205.251.252.0/23;
set_real_ip_from 204.246.176.0/20;
set_real_ip_from 13.249.0.0/16;
set_real_ip_from 54.240.128.0/18;
set_real_ip_from 205.251.250.0/23;
set_real_ip_from 52.222.128.0/17;
set_real_ip_from 54.182.0.0/16;
set_real_ip_from 54.192.0.0/16;
set_real_ip_from 13.124.199.0/24;
set_real_ip_from 34.226.14.0/24;
set_real_ip_from 52.15.127.128/26;
set_real_ip_from 35.158.136.0/24;
set_real_ip_from 52.57.254.0/24;
set_real_ip_from 18.216.170.128/25;
set_real_ip_from 13.52.204.0/23;
set_real_ip_from 13.54.63.128/26;
set_real_ip_from 13.59.250.0/26;
set_real_ip_from 13.210.67.128/26;
set_real_ip_from 35.167.191.128/26;
set_real_ip_from 52.47.139.0/24;
set_real_ip_from 52.199.127.192/26;
set_real_ip_from 52.212.248.0/26;
set_real_ip_from 52.66.194.128/26;
set_real_ip_from 13.113.203.0/24;
set_real_ip_from 99.79.168.0/23;
set_real_ip_from 34.195.252.0/24;
set_real_ip_from 35.162.63.192/26;
set_real_ip_from 34.223.12.224/27;
set_real_ip_from 52.56.127.0/25;
set_real_ip_from 34.223.80.192/26;
set_real_ip_from 13.228.69.0/24;
set_real_ip_from 34.216.51.0/25;
set_real_ip_from 3.231.2.0/25;
set_real_ip_from 54.233.255.128/26;
set_real_ip_from 18.200.212.0/23;
set_real_ip_from 52.52.191.128/26;
set_real_ip_from 3.234.232.224/27;
set_real_ip_from 52.78.247.128/26;
set_real_ip_from 52.220.191.0/26;
set_real_ip_from 34.232.163.208/29;
set_real_ip_from 2600:9000:eee::/48;
set_real_ip_from 2600:9000:4000::/36;
set_real_ip_from 2600:9000:3000::/36;
set_real_ip_from 2600:9000:f000::/36;
set_real_ip_from 2600:9000:fff::/48;
set_real_ip_from 2600:9000:2000::/36;
set_real_ip_from 2600:9000:1000::/36;
set_real_ip_from 2600:9000:ddd::/48;
set_real_ip_from 2600:9000:5300::/40;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;

View File

@ -5,7 +5,6 @@ location ^~ /.well-known/acme-challenge/ {
# Since this is for letsencrypt authentication of a domain and they do not give IP ranges of their infrastructure # Since this is for letsencrypt authentication of a domain and they do not give IP ranges of their infrastructure
# we need to open up access by turning off auth and IP ACL for this location. # we need to open up access by turning off auth and IP ACL for this location.
auth_basic off; auth_basic off;
auth_request off;
allow all; allow all;
# Set correct content type. According to this: # Set correct content type. According to this:

View File

@ -2,7 +2,5 @@ add_header X-Served-By $host;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Forwarded-Scheme $scheme; proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $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;
proxy_pass $forward_scheme://$server:$port$request_uri;

View File

@ -3,5 +3,7 @@ ssl_session_cache shared:SSL:50m;
# intermediate configuration. tweak to your needs. # intermediate configuration. tweak to your needs.
ssl_protocols TLSv1.2 TLSv1.3; ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384'; ssl_ciphers 'EECDH+AESGCM:AES256+EECDH:AES256+EDH:EDH+AESGCM:ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-
ssl_prefer_server_ciphers off; ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AE
S128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES';
ssl_prefer_server_ciphers on;

View File

@ -9,7 +9,7 @@ worker_processes auto;
# Enables the use of JIT for regular expressions to speed-up their processing. # Enables the use of JIT for regular expressions to speed-up their processing.
pcre_jit on; pcre_jit on;
error_log /data/logs/fallback_error.log warn; error_log /data/logs/error.log warn;
# Includes files with directives to load dynamic modules. # Includes files with directives to load dynamic modules.
include /etc/nginx/modules/*.conf; include /etc/nginx/modules/*.conf;
@ -46,7 +46,8 @@ http {
log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_user_agent" "$http_referer"'; log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_user_agent" "$http_referer"';
log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"'; log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"';
access_log /data/logs/fallback_access.log proxy;
access_log /data/logs/default.log proxy;
# Dynamically generated resolvers file # Dynamically generated resolvers file
include /etc/nginx/conf.d/include/resolvers.conf; include /etc/nginx/conf.d/include/resolvers.conf;
@ -57,20 +58,17 @@ http {
} }
# Real IP Determination # Real IP Determination
# Docker subnet:
set_real_ip_from 172.0.0.0/8;
# Local subnets: # Local subnets:
set_real_ip_from 10.0.0.0/8; set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12; # Includes Docker subnet set_real_ip_from 192.0.0.0/8;
set_real_ip_from 192.168.0.0/16;
# NPM generated CDN ip ranges: # NPM generated CDN ip ranges:
include conf.d/include/ip_ranges.conf; include conf.d/include/ip_ranges.conf;
# always put the following 2 lines after ip subnets: # always put the following 2 lines after ip subnets:
real_ip_header X-Real-IP; real_ip_header X-Forwarded-For;
real_ip_recursive on; real_ip_recursive on;
# Custom
include /data/nginx/custom/http_top[.]conf;
# Files generated by NPM # Files generated by NPM
include /etc/nginx/conf.d/*.conf; include /etc/nginx/conf.d/*.conf;
include /data/nginx/default_host/*.conf; include /data/nginx/default_host/*.conf;
@ -86,9 +84,6 @@ http {
stream { stream {
# Files generated by NPM # Files generated by NPM
include /data/nginx/stream/*.conf; include /data/nginx/stream/*.conf;
# Custom
include /data/nginx/custom/stream[.]conf;
} }
# Custom # Custom

View File

@ -4,7 +4,6 @@
if [ "$DEVELOPMENT" == "true" ]; then if [ "$DEVELOPMENT" == "true" ]; then
cd /app/frontend || exit 1 cd /app/frontend || exit 1
# If yarn install fails: add --verbose --network-concurrency 1
yarn install yarn install
yarn watch yarn watch
else else

View File

@ -6,7 +6,6 @@ cd /app || echo
if [ "$DEVELOPMENT" == "true" ]; then if [ "$DEVELOPMENT" == "true" ]; then
cd /app || exit 1 cd /app || exit 1
# If yarn install fails: add --verbose --network-concurrency 1
yarn install yarn install
node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js
else else

View File

@ -24,12 +24,8 @@ chown root /tmp/nginx
# Dynamically generate resolvers file, if resolver is IPv6, enclose in `[]` # Dynamically generate resolvers file, if resolver is IPv6, enclose in `[]`
# thanks @tfmm # thanks @tfmm
if [ "$DISABLE_IPV6" == "true" ] || [ "$DISABLE_IPV6" == "on" ] || [ "$DISABLE_IPV6" == "1" ] || [ "$DISABLE_IPV6" == "yes" ]; echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" > /etc/nginx/conf.d/include/resolvers.conf
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
# Generate dummy self-signed certificate. # Generate dummy self-signed certificate.
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ] if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]
then then
@ -40,7 +36,7 @@ then
-days 3650 \ -days 3650 \
-nodes \ -nodes \
-x509 \ -x509 \
-subj '/O=localhost/OU=localhost/CN=localhost' \ -subj '/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost' \
-keyout /data/nginx/dummykey.pem \ -keyout /data/nginx/dummykey.pem \
-out /data/nginx/dummycert.pem -out /data/nginx/dummycert.pem
echo "Complete" echo "Complete"

View File

@ -16,7 +16,5 @@ alias h='cd ~;clear;'
echo -e -n '\E[1;34m' echo -e -n '\E[1;34m'
figlet -w 120 "NginxProxyManager" figlet -w 120 "NginxProxyManager"
echo -e "\E[1;36mVersion \E[1;32m${NPM_BUILD_VERSION:-2.0.0-dev} (${NPM_BUILD_COMMIT:-dev}) ${NPM_BUILD_DATE:-0000-00-00}\E[1;36m, OpenResty \E[1;32m${OPENRESTY_VERSION:-unknown}\E[1;36m, ${ID:-debian} \E[1;32m${VERSION:-unknown}\E[1;36m, Certbot \E[1;32m$(certbot --version)\E[0m" echo -e "\E[1;36mVersion \E[1;32m${NPM_BUILD_VERSION:-2.0.0-dev} (${NPM_BUILD_COMMIT:-dev}) ${NPM_BUILD_DATE:-0000-00-00}\E[1;36m, OpenResty \E[1;32m${OPENRESTY_VERSION:-unknown}\E[1;36m, Alpine \E[1;32m${VERSION_ID:-unknown}\E[1;36m, Kernel \E[1;32m$(uname -r)\E[0m"
echo -e -n '\E[1;34m' echo
cat /built-for-arch
echo -e '\E[0m'

View File

@ -47,7 +47,6 @@ module.exports = {
["/screenshots/", "Screenshots"], ["/screenshots/", "Screenshots"],
["/setup/", "Setup Instructions"], ["/setup/", "Setup Instructions"],
["/advanced-config/", "Advanced Configuration"], ["/advanced-config/", "Advanced Configuration"],
["/upgrading/", "Upgrading"],
["/faq/", "Frequently Asked Questions"], ["/faq/", "Frequently Asked Questions"],
["/third-party/", "Third Party"] ["/third-party/", "Third Party"]
] ]

View File

@ -37,3 +37,72 @@ footer: MIT Licensed | Copyright © 2016-present jc21.com
<p>Configure other users to either view or manage their own hosts. Full access permissions are available.</p> <p>Configure other users to either view or manage their own hosts. Full access permissions are available.</p>
</div> </div>
</div> </div>
### Quick Setup
1. Install Docker and Docker-Compose
- [Docker Install documentation](https://docs.docker.com/install/)
- [Docker-Compose Install documentation](https://docs.docker.com/compose/install/)
2. Create a config file for example
```json
{
"database": {
"engine": "mysql",
"host": "db",
"name": "npm",
"user": "npm",
"password": "npm",
"port": 3306
}
}
```
3. Create a docker-compose.yml file similar to this:
```yml
version: '3'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./config.json:/app/config/production.json
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
db:
image: 'jc21/mariadb-aria:10.4'
environment:
MYSQL_ROOT_PASSWORD: 'npm'
MYSQL_DATABASE: 'npm'
MYSQL_USER: 'npm'
MYSQL_PASSWORD: 'npm'
volumes:
- ./data/mysql:/var/lib/mysql
```
4. Bring up your stack
```bash
docker-compose up -d
```
5. Log in to the Admin UI
When your docker container is running, connect to it on port `81` for the admin interface.
Sometimes this can take a little bit because of the entropy of keys.
[http://127.0.0.1:81](http://127.0.0.1:81)
Default Admin User:
```
Email: admin@example.com
Password: changeme
```
Immediately after logging in with this default user you will be asked to modify your details and change your password.

View File

@ -1,134 +1,8 @@
# Advanced Configuration # Advanced Configuration
## Best Practice: Use a Docker network
For those who have a few of their upstream services running in Docker on the same Docker
host as NPM, here's a trick to secure things a bit better. By creating a custom Docker network,
you don't need to publish ports for your upstream services to all of the Docker host's interfaces.
Create a network, ie "scoobydoo":
```bash
docker network create scoobydoo
```
Then add the following to the `docker-compose.yml` file for both NPM and any other
services running on this Docker host:
```yml
networks:
default:
external: true
name: scoobydoo
```
Let's look at a Portainer example:
```yml
version: '3'
services:
portainer:
image: portainer/portainer
privileged: true
volumes:
- './data:/data'
- '/var/run/docker.sock:/var/run/docker.sock'
restart: unless-stopped
networks:
default:
external: true
name: scoobydoo
```
Now in the NPM UI you can create a proxy host with `portainer` as the hostname,
and port `9000` as the port. Even though this port isn't listed in the docker-compose
file, it's "exposed" by the Portainer Docker image for you and not available on
the Docker host outside of this Docker network. The service name is used as the
hostname, so make sure your service names are unique when using the same network.
## Docker Healthcheck
The `Dockerfile` that builds this project does not include a `HEALTHCHECK` but you can opt in to this
feature by adding the following to the service in your `docker-compose.yml` file:
```yml
healthcheck:
test: ["CMD", "/bin/check-health"]
interval: 10s
timeout: 3s
```
## Docker Secrets
This image supports the use of Docker secrets to import from file and keep sensitive usernames or passwords from being passed or preserved in plaintext.
You can set any environment variable from a file by appending `__FILE` (double-underscore FILE) to the environmental variable name.
```yml
version: "3.7"
secrets:
# Secrets are single-line text files where the sole content is the secret
# Paths in this example assume that secrets are kept in local folder called ".secrets"
DB_ROOT_PWD:
file: .secrets/db_root_pwd.txt
MYSQL_PWD:
file: .secrets/mysql_pwd.txt
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
# Public HTTP Port:
- '80:80'
# Public HTTPS Port:
- '443:443'
# Admin Web Port:
- '81:81'
environment:
# These are the settings to access your db
DB_MYSQL_HOST: "db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
# DB_MYSQL_PASSWORD: "npm" # use secret instead
DB_MYSQL_PASSWORD__FILE: /run/secrets/MYSQL_PWD
DB_MYSQL_NAME: "npm"
# If you would rather use Sqlite uncomment this
# and remove all DB_MYSQL_* lines above
# DB_SQLITE_FILE: "/data/database.sqlite"
# Uncomment this if IPv6 is not enabled on your host
# DISABLE_IPV6: 'true'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
secrets:
- MYSQL_PWD
depends_on:
- db
db:
image: jc21/mariadb-aria
restart: unless-stopped
environment:
# MYSQL_ROOT_PASSWORD: "npm" # use secret instead
MYSQL_ROOT_PASSWORD__FILE: /run/secrets/DB_ROOT_PWD
MYSQL_DATABASE: "npm"
MYSQL_USER: "npm"
# MYSQL_PASSWORD: "npm" # use secret instead
MYSQL_PASSWORD__FILE: /run/secrets/MYSQL_PWD
volumes:
- ./data/mysql:/var/lib/mysql
secrets:
- DB_ROOT_PWD
- MYSQL_PWD
```
## Disabling IPv6 ## Disabling IPv6
On some Docker hosts IPv6 may not be enabled. In these cases, the following message may be seen in the log: On some docker hosts IPv6 may not be enabled. In these cases, the following message may be seen in the log:
> Address family not supported by protocol > Address family not supported by protocol
@ -149,9 +23,7 @@ NPM has the ability to include different custom configuration snippets in differ
You can add your custom configuration snippet files at `/data/nginx/custom` as follow: You can add your custom configuration snippet files at `/data/nginx/custom` as follow:
- `/data/nginx/custom/root.conf`: Included at the very end of nginx.conf - `/data/nginx/custom/root.conf`: Included at the very end of nginx.conf
- `/data/nginx/custom/http_top.conf`: Included at the top of the main http block
- `/data/nginx/custom/http.conf`: Included at the end of the main http block - `/data/nginx/custom/http.conf`: Included at the end of the main http block
- `/data/nginx/custom/stream.conf`: Included at the end of the main stream block
- `/data/nginx/custom/server_proxy.conf`: Included at the end of every proxy server block - `/data/nginx/custom/server_proxy.conf`: Included at the end of every proxy server block
- `/data/nginx/custom/server_redirect.conf`: Included at the end of every redirection server block - `/data/nginx/custom/server_redirect.conf`: Included at the end of every redirection server block
- `/data/nginx/custom/server_stream.conf`: Included at the end of every stream server block - `/data/nginx/custom/server_stream.conf`: Included at the end of every stream server block

View File

@ -14,13 +14,3 @@ of dependencies.
Yes! The docker image is multi-arch and is built for a variety of architectures. If yours is Yes! The docker image is multi-arch and is built for a variety of architectures. If yours is
[not listed](https://hub.docker.com/r/jc21/nginx-proxy-manager/tags) please open a [not listed](https://hub.docker.com/r/jc21/nginx-proxy-manager/tags) please open a
[GitHub issue](https://github.com/jc21/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=). [GitHub issue](https://github.com/jc21/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=).
## I can't get my service to proxy properly?
Your best bet is to ask the [Reddit community for support](https://www.reddit.com/r/nginxproxymanager/). There's safety in numbers.
Gitter is best left for anyone contributing to the project to ask for help about internals, code reviews etc.
## 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

@ -143,7 +143,7 @@
"css-select-base-adapter": "^0.1.1", "css-select-base-adapter": "^0.1.1",
"css-tree": "^1.0.0-alpha.39", "css-tree": "^1.0.0-alpha.39",
"css-unit-converter": "^1.1.2", "css-unit-converter": "^1.1.2",
"css-what": "^5.0.1", "css-what": "^3.3.0",
"cssesc": "^3.0.0", "cssesc": "^3.0.0",
"cssnano": "^4.1.10", "cssnano": "^4.1.10",
"cssnano-preset-default": "^4.0.7", "cssnano-preset-default": "^4.0.7",
@ -213,7 +213,7 @@
"etag": "^1.8.1", "etag": "^1.8.1",
"eventemitter3": "^4.0.4", "eventemitter3": "^4.0.4",
"events": "^3.2.0", "events": "^3.2.0",
"eventsource": "^2.0.2", "eventsource": "^1.0.7",
"evp_bytestokey": "^1.0.3", "evp_bytestokey": "^1.0.3",
"execa": "^4.0.3", "execa": "^4.0.3",
"expand-brackets": "^4.0.0", "expand-brackets": "^4.0.0",
@ -357,7 +357,7 @@
"jsbn": "^1.1.0", "jsbn": "^1.1.0",
"jsesc": "^3.0.1", "jsesc": "^3.0.1",
"json-parse-better-errors": "^1.0.2", "json-parse-better-errors": "^1.0.2",
"json-schema": "^0.4.0", "json-schema": "^0.2.5",
"json-schema-traverse": "^0.4.1", "json-schema-traverse": "^0.4.1",
"json-stringify-safe": "^5.0.1", "json-stringify-safe": "^5.0.1",
"json3": "^3.3.3", "json3": "^3.3.3",
@ -394,7 +394,7 @@
"map-age-cleaner": "^0.1.3", "map-age-cleaner": "^0.1.3",
"map-cache": "^0.2.2", "map-cache": "^0.2.2",
"map-visit": "^1.0.0", "map-visit": "^1.0.0",
"markdown-it": "^12.3.2", "markdown-it": "^11.0.0",
"markdown-it-anchor": "^5.3.0", "markdown-it-anchor": "^5.3.0",
"markdown-it-chain": "^1.3.0", "markdown-it-chain": "^1.3.0",
"markdown-it-container": "^3.0.0", "markdown-it-container": "^3.0.0",
@ -434,7 +434,7 @@
"neo-async": "^2.6.2", "neo-async": "^2.6.2",
"nice-try": "^2.0.1", "nice-try": "^2.0.1",
"no-case": "^3.0.3", "no-case": "^3.0.3",
"node-forge": "^1.0.0", "node-forge": "^0.10.0",
"node-libs-browser": "^2.2.1", "node-libs-browser": "^2.2.1",
"node-releases": "^1.1.60", "node-releases": "^1.1.60",
"nopt": "^4.0.3", "nopt": "^4.0.3",
@ -443,7 +443,7 @@
"normalize-url": "^5.1.0", "normalize-url": "^5.1.0",
"npm-run-path": "^4.0.1", "npm-run-path": "^4.0.1",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"nth-check": "^2.0.1", "nth-check": "^1.0.2",
"num2fraction": "^1.2.2", "num2fraction": "^1.2.2",
"number-is-nan": "^2.0.0", "number-is-nan": "^2.0.0",
"oauth-sign": "^0.9.0", "oauth-sign": "^0.9.0",
@ -500,7 +500,7 @@
"pkg-up": "^3.1.0", "pkg-up": "^3.1.0",
"portfinder": "^1.0.28", "portfinder": "^1.0.28",
"posix-character-classes": "^1.0.0", "posix-character-classes": "^1.0.0",
"postcss": "^8.2.10", "postcss": "^7.0.32",
"postcss-calc": "^7.0.2", "postcss-calc": "^7.0.2",
"postcss-colormin": "^4.0.3", "postcss-colormin": "^4.0.3",
"postcss-convert-values": "^4.0.1", "postcss-convert-values": "^4.0.1",
@ -612,7 +612,7 @@
"serve-index": "^1.9.1", "serve-index": "^1.9.1",
"serve-static": "^1.14.1", "serve-static": "^1.14.1",
"set-blocking": "^2.0.0", "set-blocking": "^2.0.0",
"set-value": "^4.0.1", "set-value": "^3.0.2",
"setimmediate": "^1.0.5", "setimmediate": "^1.0.5",
"setprototypeof": "^1.2.0", "setprototypeof": "^1.2.0",
"sha.js": "^2.4.11", "sha.js": "^2.4.11",

View File

@ -1,44 +1,51 @@
# Full Setup Instructions # Full Setup Instructions
## Running the App ### Configuration File
Create a `docker-compose.yml` file: **The configuration file needs to be provided by you!**
```yml Don't worry, this is easy to do.
version: "3"
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
# These ports are in format <host-port>:<container-port>
- '80:80' # Public HTTP Port
- '443:443' # Public HTTPS Port
- '81:81' # Admin Web Port
# Add any other Stream port you want to expose
# - '21:21' # FTP
# Uncomment the next line if you uncomment anything in the section The app requires a configuration file to let it know what database you're using. By default, this file is called `config.json`
# environment:
# Uncomment this if you want to change the location of
# the SQLite DB file within the container
# DB_SQLITE_FILE: "/data/database.sqlite"
# Uncomment this if IPv6 is not enabled on your host Here's an example configuration for `mysql` (or mariadb) that is compatible with the docker-compose example below:
# DISABLE_IPV6: 'true'
volumes: ```json
- ./data:/data {
- ./letsencrypt:/etc/letsencrypt "database": {
"engine": "mysql",
"host": "db",
"name": "npm",
"user": "npm",
"password": "npm",
"port": 3306
}
}
``` ```
Then: Alternatively if you would like to use a Sqlite database file:
```bash ```json
docker-compose up -d {
"database": {
"engine": "knex-native",
"knex": {
"client": "sqlite3",
"connection": {
"filename": "/data/database.sqlite"
}
}
}
}
``` ```
## Using MySQL / MariaDB Database Once you've created your configuration file it's easy to mount it in the docker container.
**Note:** After the first run of the application, the config file will be altered to include generated encryption keys unique to your installation. These keys
affect the login and session management of the application. If these keys change for any reason, all users will be logged out.
### MySQL Database
If you opt for the MySQL configuration you will have to provide the database server yourself. You can also use MariaDB. Here are the minimum supported versions: If you opt for the MySQL configuration you will have to provide the database server yourself. You can also use MariaDB. Here are the minimum supported versions:
@ -48,38 +55,43 @@ If you opt for the MySQL configuration you will have to provide the database ser
It's easy to use another docker container for your database also and link it as part of the docker stack, so that's what the following examples It's easy to use another docker container for your database also and link it as part of the docker stack, so that's what the following examples
are going to use. are going to use.
Here is an example of what your `docker-compose.yml` will look like when using a MariaDB container: ::: warning
When using a `mariadb` database, the NPM configuration file should still use the `mysql` engine!
:::
### Running the App
Via `docker-compose`:
```yml ```yml
version: "3" version: "3"
services: services:
app: app:
image: 'jc21/nginx-proxy-manager:latest' image: jc21/nginx-proxy-manager:2
restart: unless-stopped restart: always
ports: ports:
# These ports are in format <host-port>:<container-port> # Public HTTP Port:
- '80:80' # Public HTTP Port - '80:80'
- '443:443' # Public HTTPS Port # Public HTTPS Port:
- '81:81' # Admin Web Port - '443:443'
# Add any other Stream port you want to expose # Admin Web Port:
# - '21:21' # FTP - '81:81'
environment: environment:
DB_MYSQL_HOST: "db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
DB_MYSQL_PASSWORD: "npm"
DB_MYSQL_NAME: "npm"
# Uncomment this if IPv6 is not enabled on your host # Uncomment this if IPv6 is not enabled on your host
# DISABLE_IPV6: 'true' # DISABLE_IPV6: 'true'
volumes: volumes:
# Make sure this config.json file exists as per instructions above:
- ./config.json:/app/config/production.json
- ./data:/data - ./data:/data
- ./letsencrypt:/etc/letsencrypt - ./letsencrypt:/etc/letsencrypt
depends_on: depends_on:
- db - db
db: db:
image: 'jc21/mariadb-aria:latest' image: jc21/mariadb-aria:10.4
restart: unless-stopped restart: always
environment: environment:
MYSQL_ROOT_PASSWORD: 'npm' MYSQL_ROOT_PASSWORD: 'npm'
MYSQL_DATABASE: 'npm' MYSQL_DATABASE: 'npm'
@ -89,13 +101,15 @@ services:
- ./data/mysql:/var/lib/mysql - ./data/mysql:/var/lib/mysql
``` ```
::: warning Then:
Please note, that `DB_MYSQL_*` environment variables will take precedent over `DB_SQLITE_*` variables. So if you keep the MySQL variables, you will not be able to use SQLite. ```bash
docker-compose up -d
```
::: The config file (config.json) must be present in this directory.
## Running on Raspberry PI / ARM devices ### Running on Raspberry PI / ARM devices
The docker images support the following architectures: The docker images support the following architectures:
- amd64 - amd64
@ -107,14 +121,13 @@ 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) 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, 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/) Also, if you don't know how to already, follow [this guide to install docker and docker-compose](https://manre-universe.net/how-to-run-docker-and-docker-compose-on-raspbian/)
on Raspbian. on Raspbian.
Please note that the `jc21/mariadb-aria:latest` image might have some problems on some ARM devices, if you want a separate database container, use the `yobasystems/alpine-mariadb:latest` image.
## Initial Run ### Initial Run
After the app is running for the first time, the following will happen: After the app is running for the first time, the following will happen:
@ -125,7 +138,7 @@ After the app is running for the first time, the following will happen:
This process can take a couple of minutes depending on your machine. This process can take a couple of minutes depending on your machine.
## Default Administrator User ### Default Administrator User
``` ```
Email: admin@example.com Email: admin@example.com
@ -133,50 +146,3 @@ Password: changeme
``` ```
Immediately after logging in with this default user you will be asked to modify your details and change your password. Immediately after logging in with this default user you will be asked to modify your details and change your password.
## Configuration File
::: warning
This section is meant for advanced users
:::
If you would like more control over the database settings you can define a custom config JSON file.
Here's an example for `sqlite` configuration as it is generated from the environment variables:
```json
{
"database": {
"engine": "knex-native",
"knex": {
"client": "sqlite3",
"connection": {
"filename": "/data/database.sqlite"
},
"useNullAsDefault": true
}
}
}
```
You can modify the `knex` object with your custom configuration, but note that not all knex clients might be installed in the image.
Once you've created your configuration file you can mount it to `/app/config/production.json` inside you container using:
```
[...]
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
[...]
volumes:
- ./config.json:/app/config/production.json
[...]
[...]
```
**Note:** After the first run of the application, the config file will be altered to include generated encryption keys unique to your installation.
These keys affect the login and session management of the application. If these keys change for any reason, all users will be logged out.

View File

@ -1,16 +1,12 @@
# Third Party # 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. integrations, they are *not supported* by me.
Known integrations: Known integrations:
- [HomeAssistant Hass.io plugin](https://github.com/hassio-addons/addon-nginx-proxy-manager) - [HomeAssistant Hass.io plugin](https://github.com/hassio-addons/addon-nginx-proxy-manager)
- [UnRaid / Synology](https://github.com/jlesage/docker-nginx-proxy-manager) - [UnRaid / Synology](https://github.com/jlesage/docker-nginx-proxy-manager)
- [Proxmox Scripts](https://github.com/ej52/proxmox-scripts/tree/main/lxc/nginx-proxy-manager)
- [nginxproxymanagerGraf](https://github.com/ma-karai/nginxproxymanagerGraf)
If you would like your integration of NPM listed, please open a If you would like your integration of NPM listed, please open a
[Github issue](https://github.com/jc21/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=) [Github issue](https://github.com/jc21/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=)

View File

@ -1,11 +0,0 @@
# Upgrading
```bash
docker-compose pull
docker-compose up -d
```
This project will automatically update any databases or other requirements so you don't have to follow
any crazy instructions. These steps above will pull the latest updates and recreate the docker
containers.

View File

@ -967,46 +967,6 @@
lodash "^4.17.19" lodash "^4.17.19"
to-fast-properties "^2.0.0" 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": "@mrmlnc/readdir-enhanced@^2.2.1":
version "2.2.1" version "2.2.1"
resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" 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" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c"
integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w== 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: agentkeepalive@^2.2.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-2.2.0.tgz#c5d1bd4b129008f1163f236f86e5faea2026e2ef" resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-2.2.0.tgz#c5d1bd4b129008f1163f236f86e5faea2026e2ef"
@ -1669,9 +1624,9 @@ ansi-regex@^4.1.0:
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
ansi-regex@^5.0.0: ansi-regex@^5.0.0:
version "5.0.1" version "5.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
ansi-styles@^2.2.1: ansi-styles@^2.2.1:
version "2.2.1" version "2.2.1"
@ -1731,11 +1686,6 @@ argparse@^1.0.10, argparse@^1.0.7:
dependencies: dependencies:
sprintf-js "~1.0.2" 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: arr-diff@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
@ -2050,10 +2000,10 @@ bluebird@^3.1.1, bluebird@^3.5.5, bluebird@^3.7.2:
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0:
version "4.12.0" version "4.11.9"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828"
integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==
bn.js@^5.1.1, bn.js@^5.1.2: bn.js@^5.1.1, bn.js@^5.1.2:
version "5.1.2" version "5.1.2"
@ -2205,15 +2155,14 @@ browserify-zlib@^0.2.0:
pako "~1.0.5" pako "~1.0.5"
browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.13.0, browserslist@^4.8.5: browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.13.0, browserslist@^4.8.5:
version "4.16.5" version "4.13.0"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.5.tgz#952825440bca8913c62d0021334cbe928ef062ae" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.13.0.tgz#42556cba011e1b0a2775b611cba6a8eca18e940d"
integrity sha512-C2HAjrM1AI/djrpAUU/tr4pml1DqLIzJKSLDBXBrNErl9ZCCTXdhwxdJjYc16953+mBWf7Lw+uUJgpgb8cN71A== integrity sha512-MINatJ5ZNrLnQ6blGvePd/QOz9Xtu+Ne+x29iQSCHfkU5BugKVJwZKn/iiL8UbpIpa3JhviKjz+XxMo0m2caFQ==
dependencies: dependencies:
caniuse-lite "^1.0.30001214" caniuse-lite "^1.0.30001093"
colorette "^1.2.2" electron-to-chromium "^1.3.488"
electron-to-chromium "^1.3.719" escalade "^3.0.1"
escalade "^3.1.1" node-releases "^1.1.58"
node-releases "^1.1.71"
buffer-from@^1.0.0, buffer-from@^1.1.1: buffer-from@^1.0.0, buffer-from@^1.1.1:
version "1.1.1" version "1.1.1"
@ -2468,10 +2417,10 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2" lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0" lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001111, caniuse-lite@^1.0.30001214: caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001093, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001111:
version "1.0.30001230" version "1.0.30001111"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz#8135c57459854b2240b57a4a6786044bdc5a9f71" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001111.tgz#dd0ce822c70eb6c7c068e4a55c22e19ec1501298"
integrity sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ== integrity sha512-xnDje2wchd/8mlJu8sXvWxOGvMgv+uT3iZ3bkIAynKOzToCssWCmkz/ZIkQBs/2pUB4uwnJKVORWQ31UkbVjOg==
caseless@^0.12.0, caseless@~0.12.0: caseless@^0.12.0, caseless@~0.12.0:
version "0.12.0" version "0.12.0"
@ -2610,7 +2559,7 @@ cli-boxes@^2.2.0:
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d"
integrity sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w== integrity sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==
clipboard@^2.0.6: clipboard@^2.0.0, clipboard@^2.0.6:
version "2.0.6" version "2.0.6"
resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.6.tgz#52921296eec0fdf77ead1749421b21c968647376" resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.6.tgz#52921296eec0fdf77ead1749421b21c968647376"
integrity sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg== integrity sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==
@ -2700,9 +2649,9 @@ color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4:
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
color-string@^1.5.2, color-string@^1.5.3: color-string@^1.5.2, color-string@^1.5.3:
version "1.5.5" version "1.5.3"
resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.5.tgz#65474a8f0e7439625f3d27a6a19d89fc45223014" resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc"
integrity sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg== integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==
dependencies: dependencies:
color-name "^1.0.0" color-name "^1.0.0"
simple-swizzle "^0.2.2" simple-swizzle "^0.2.2"
@ -2715,10 +2664,10 @@ color@^3.0.0, color@^3.1.2:
color-convert "^1.9.1" color-convert "^1.9.1"
color-string "^1.5.2" color-string "^1.5.2"
colorette@^1.2.1, colorette@^1.2.2: colorette@^1.2.1:
version "1.2.2" version "1.2.1"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b"
integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==
combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
version "1.0.8" version "1.0.8"
@ -3164,16 +3113,11 @@ css-what@2.1:
resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2"
integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==
css-what@^3.2.1: css-what@^3.2.1, css-what@^3.3.0:
version "3.3.0" version "3.3.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.3.0.tgz#10fec696a9ece2e591ac772d759aacabac38cd39" resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.3.0.tgz#10fec696a9ece2e591ac772d759aacabac38cd39"
integrity sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg== integrity sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==
css-what@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.0.1.tgz#3efa820131f4669a8ac2408f9c32e7c7de9f4cad"
integrity sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==
css@^2.0.0: css@^2.0.0:
version "2.2.4" version "2.2.4"
resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929"
@ -3551,9 +3495,9 @@ dns-packet@^4.0.0:
safe-buffer "^5.1.1" safe-buffer "^5.1.1"
dns-packet@^5.2.1: dns-packet@^5.2.1:
version "5.2.2" version "5.2.1"
resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.2.2.tgz#e4c7d12974cc320b0c0d4b9bbbf68ac151cfe81e" resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.2.1.tgz#26cec0be92252a1b97ed106482921192a7e08f72"
integrity sha512-sQN+vLwC3PvOXiCH/oHcdzML2opFeIdVh8gjjMZrM45n4dR80QF6o3AzInQy6F9Eoc0VJYog4JpQTilt4RFLYQ== integrity sha512-JHj2yJeKOqlxzeuYpN1d56GfhzivAxavNwHj9co3qptECel27B1rLY5PifJAvubsInX5pGLDjAHuCfCUc2Zv/w==
dependencies: dependencies:
ip "^1.1.5" ip "^1.1.5"
@ -3725,23 +3669,23 @@ ee-first@1.1.1, ee-first@^1.1.1:
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
electron-to-chromium@^1.3.522, electron-to-chromium@^1.3.719: electron-to-chromium@^1.3.488, electron-to-chromium@^1.3.522:
version "1.3.739" version "1.3.522"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.739.tgz#f07756aa92cabd5a6eec6f491525a64fe62f98b9" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.522.tgz#4a6485ad187ffd31913bba0747d0e36405f405d6"
integrity sha512-+LPJVRsN7hGZ9EIUUiWCpO7l4E3qBYHNadazlucBfsXBbccDFNKUBAgzE68FnkWGJPwD/AfKhSzL+G+Iqb8A4A== integrity sha512-67V62Z4CFOiAtox+o+tosGfVk0QX4DJgH609tjT8QymbJZVAI/jWnAthnr8c5hnRNziIRwkc9EMQYejiVz3/9Q==
elliptic@^6.5.3: elliptic@^6.5.3:
version "6.5.4" version "6.5.3"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6"
integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==
dependencies: dependencies:
bn.js "^4.11.9" bn.js "^4.4.0"
brorand "^1.1.0" brorand "^1.0.1"
hash.js "^1.0.0" hash.js "^1.0.0"
hmac-drbg "^1.0.1" hmac-drbg "^1.0.0"
inherits "^2.0.4" inherits "^2.0.1"
minimalistic-assert "^1.0.1" minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1" minimalistic-crypto-utils "^1.0.0"
emoji-regex@^7.0.1: emoji-regex@^7.0.1:
version "7.0.3" version "7.0.3"
@ -3794,10 +3738,10 @@ entities@^1.1.1, entities@~1.1.1:
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
entities@^2.0.0, entities@^2.0.3, entities@~2.1.0: entities@^2.0.0, entities@^2.0.3, entities@~2.0.0:
version "2.1.0" version "2.0.3"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f"
integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==
envify@^4.0.0, envify@^4.1.0: envify@^4.0.0, envify@^4.1.0:
version "4.1.0" version "4.1.0"
@ -3875,10 +3819,10 @@ es6-promise@^4.1.0, es6-promise@^4.2.8:
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
escalade@^3.1.1: escalade@^3.0.1:
version "3.1.1" version "3.0.2"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4"
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== integrity sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ==
escape-goat@^2.0.0: escape-goat@^2.0.0:
version "2.1.1" version "2.1.1"
@ -3975,11 +3919,6 @@ eventsource@^1.0.7:
dependencies: dependencies:
original "^1.0.0" 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: evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
@ -4167,13 +4106,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" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 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: fastq@^1.6.0:
version "1.8.0" version "1.8.0"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481"
@ -4316,9 +4248,9 @@ flush-write-stream@^2.0.0:
readable-stream "^3.1.1" readable-stream "^3.1.1"
follow-redirects@^1.0.0, follow-redirects@^1.12.1: follow-redirects@^1.0.0, follow-redirects@^1.12.1:
version "1.14.8" version "1.12.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.12.1.tgz#de54a6205311b93d60398ebc01cf7015682312b6"
integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA== integrity sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg==
for-in@^1.0.2: for-in@^1.0.2:
version "1.0.2" version "1.0.2"
@ -4489,9 +4421,9 @@ glob-parent@^3.1.0:
path-dirname "^1.0.0" path-dirname "^1.0.0"
glob-parent@^5.1.0, glob-parent@^5.1.1, glob-parent@~5.1.0: glob-parent@^5.1.0, glob-parent@^5.1.1, glob-parent@~5.1.0:
version "5.1.2" version "5.1.1"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==
dependencies: dependencies:
is-glob "^4.0.1" is-glob "^4.0.1"
@ -4795,7 +4727,7 @@ hex-color-regex@^1.1.0:
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
hmac-drbg@^1.0.1: hmac-drbg@^1.0.0, hmac-drbg@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
@ -5193,9 +5125,9 @@ inherits@2.0.3:
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
ini@^1.3.5, ini@~1.3.0: ini@^1.3.5, ini@~1.3.0:
version "1.3.8" version "1.3.5"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
internal-ip@^4.3.0: internal-ip@^4.3.0:
version "4.3.0" version "4.3.0"
@ -5592,11 +5524,11 @@ is-svg@^3.0.0:
html-comment-regex "^1.1.0" html-comment-regex "^1.1.0"
is-svg@^4.2.1: is-svg@^4.2.1:
version "4.3.0" version "4.2.1"
resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-4.3.0.tgz#3e46a45dcdb2780e42a3c8538154d7f7bfc07216" resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-4.2.1.tgz#095b496e345fec9211c2a7d5d021003e040d6f81"
integrity sha512-Np3TOGLVr0J27VDaS/gVE7bT45ZcSmX4pMmMTsPjqO8JY383fuPIcWmZr3QsHVWhqhZWxSdmW+tkkl3PWOB0Nw== integrity sha512-PHx3ANecKsKNl5y5+Jvt53Y4J7MfMpbNZkv384QNiswMKAWIbvcqbPz+sYbFKJI8Xv3be01GSFniPmoaP+Ai5A==
dependencies: dependencies:
fast-xml-parser "^3.19.0" html-comment-regex "^1.1.2"
is-symbol@^1.0.2, is-symbol@^1.0.3: is-symbol@^1.0.2, is-symbol@^1.0.3:
version "1.0.3" version "1.0.3"
@ -5776,10 +5708,10 @@ json-schema@0.2.3:
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-schema@^0.4.0: json-schema@^0.2.5:
version "0.4.0" version "0.2.5"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.5.tgz#97997f50972dd0500214e208c407efa4b5d7063b"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== integrity sha512-gWJOWYFrhQ8j7pVm0EM8Slr+EPVq1Phf6lvzvD/WCeqkrx/f2xBI0xOsRRS9xCn3I4vKtP519dvs3TP09r24wQ==
json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
version "5.0.1" version "5.0.1"
@ -5977,9 +5909,9 @@ loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4
json5 "^1.0.1" json5 "^1.0.1"
loader-utils@^2.0.0: loader-utils@^2.0.0:
version "2.0.3" version "2.0.0"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.3.tgz#d4b15b8504c63d1fc3f2ade52d41bc8459d6ede1" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0"
integrity sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A== integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==
dependencies: dependencies:
big.js "^5.2.2" big.js "^5.2.2"
emojis-list "^3.0.0" emojis-list "^3.0.0"
@ -6061,9 +5993,9 @@ lodash.uniq@^4.5.0:
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.3, lodash@^4.17.5: lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.3, lodash@^4.17.5:
version "4.17.21" version "4.17.19"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
loglevel@^1.6.8: loglevel@^1.6.8:
version "1.6.8" version "1.6.8"
@ -6197,13 +6129,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" 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== integrity sha512-TAIHTHPwa9+ltKvKPWulm/beozQU41Ab+FIefRaQV1NRnpzwcV9QOe6wXQS5WLivm5Q/nlo0rl6laGkMDZE7Gw==
markdown-it@^12.3.2: markdown-it@^11.0.0:
version "12.3.2" version "11.0.0"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90" resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-11.0.0.tgz#dbfc30363e43d756ebc52c38586b91b90046b876"
integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg== integrity sha512-+CvOnmbSubmQFSA9dKz1BRiaSMV7rhexl3sngKqFyXSagoA3fBdJQ8oZWtRy2knXdpDXaBw44euz37DeJQ9asg==
dependencies: dependencies:
argparse "^2.0.1" argparse "^1.0.7"
entities "~2.1.0" entities "~2.0.0"
linkify-it "^3.0.1" linkify-it "^3.0.1"
mdurl "^1.0.1" mdurl "^1.0.1"
uc.micro "^1.0.5" uc.micro "^1.0.5"
@ -6422,7 +6354,7 @@ minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
minimalistic-crypto-utils@^1.0.1: minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
@ -6467,10 +6399,10 @@ minipass@^3.0.0, minipass@^3.1.1:
dependencies: dependencies:
yallist "^4.0.0" yallist "^4.0.0"
minizlib@^2.1.1: minizlib@^2.1.0:
version "2.1.2" version "2.1.0"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.0.tgz#fd52c645301ef09a63a2c209697c294c6ce02cf3"
integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== integrity sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==
dependencies: dependencies:
minipass "^3.0.0" minipass "^3.0.0"
yallist "^4.0.0" yallist "^4.0.0"
@ -6595,11 +6527,6 @@ nanoid@^2.0.3:
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280"
integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA== integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==
nanoid@^3.1.22:
version "3.1.23"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==
nanomatch@^1.2.13, nanomatch@^1.2.9: nanomatch@^1.2.13, nanomatch@^1.2.9:
version "1.2.13" version "1.2.13"
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
@ -6657,10 +6584,10 @@ node-forge@0.9.0:
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579"
integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ== integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==
node-forge@^1.0.0: node-forge@^0.10.0:
version "1.0.0" version "0.10.0"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.0.0.tgz#a025e3beeeb90d9cee37dae34d25b968ec3e6f15" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
integrity sha512-ShkiiAlzSsgH1IwGlA0jybk9vQTIOLyJ9nBd0JTuP+nzADJFLY0NoDijM2zvD/JaezooGu3G2p2FNxOAK6459g== integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==
node-libs-browser@^2.2.1: node-libs-browser@^2.2.1:
version "2.2.1" version "2.2.1"
@ -6691,10 +6618,10 @@ node-libs-browser@^2.2.1:
util "^0.11.0" util "^0.11.0"
vm-browserify "^1.0.1" vm-browserify "^1.0.1"
node-releases@^1.1.60, node-releases@^1.1.71: node-releases@^1.1.58, node-releases@^1.1.60:
version "1.1.72" version "1.1.60"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084"
integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== integrity sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==
nopt@1.0.10: nopt@1.0.10:
version "1.0.10" version "1.0.10"
@ -6758,9 +6685,9 @@ normalize-url@^4.1.0:
integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==
normalize-url@^5.1.0: normalize-url@^5.1.0:
version "5.3.1" version "5.1.0"
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-5.3.1.tgz#c8485c0f5ba2f9c17a6d2907b56117ae5967f882" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-5.1.0.tgz#04b8f1b34ea49ff713fc20b2218eba41fb9974a3"
integrity sha512-K1c7+vaAP+Yh5bOGmA10PGPpp+6h7WZrl7GwqKhUflBc9flU9pzG27DDeB9+iuhZkE3BJZOcgN1P/2sS5pqrWw== integrity sha512-UxHuSWsSAmzSqN+DSjasaZWQ3QPtEisHdlr4y9MJ5zg0RcImv5fQt8QM0izJSCdsdmhJGK+ubcTpJXwVDmwSVQ==
npm-run-path@^2.0.0: npm-run-path@^2.0.0:
version "2.0.2" version "2.0.2"
@ -6788,13 +6715,6 @@ nth-check@^1.0.2, nth-check@~1.0.1:
dependencies: dependencies:
boolbase "~1.0.0" boolbase "~1.0.0"
nth-check@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2"
integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==
dependencies:
boolbase "^1.0.0"
num2fraction@^1.2.2: num2fraction@^1.2.2:
version "1.2.2" version "1.2.2"
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
@ -7242,9 +7162,9 @@ path-key@^3.0.0, path-key@^3.1.0, path-key@^3.1.1:
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
path-parse@^1.0.6: path-parse@^1.0.6:
version "1.0.7" version "1.0.6"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
path-to-regexp@0.1.7: path-to-regexp@0.1.7:
version "0.1.7" version "0.1.7"
@ -7720,15 +7640,6 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.2
source-map "^0.6.1" source-map "^0.6.1"
supports-color "^6.1.0" supports-color "^6.1.0"
postcss@^8.2.10:
version "8.2.10"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.10.tgz#ca7a042aa8aff494b334d0ff3e9e77079f6f702b"
integrity sha512-b/h7CPV7QEdrqIxtAf2j31U5ef05uBDuvoXv6L51Q4rcS1jdlXAVKJv+atCFdUXYl9dyTHGyoMzIepwowRJjFw==
dependencies:
colorette "^1.2.2"
nanoid "^3.1.22"
source-map "^0.6.1"
prepend-http@^1.0.0: prepend-http@^1.0.0:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
@ -7768,9 +7679,11 @@ pretty-time@^1.1.0:
integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA== integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==
prismjs@^1.13.0, prismjs@^1.20.0: prismjs@^1.13.0, prismjs@^1.20.0:
version "1.27.0" version "1.21.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.21.0.tgz#36c086ec36b45319ec4218ee164c110f9fc015a3"
integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== integrity sha512-uGdSIu1nk3kej2iZsLyDoJ7e9bnPzIgY0naW/HdknGj61zScaprVEVGHrPoXqI+M9sP0NDnTK2jpkvmldpuqDw==
optionalDependencies:
clipboard "^2.0.0"
private@^0.1.8: private@^0.1.8:
version "0.1.8" version "0.1.8"
@ -8489,9 +8402,9 @@ set-blocking@^2.0.0:
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
set-getter@^0.1.0: set-getter@^0.1.0:
version "0.1.1" version "0.1.0"
resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.1.tgz#a3110e1b461d31a9cfc8c5c9ee2e9737ad447102" resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376"
integrity sha512-9sVWOy+gthr+0G9DzqqLaYNA7+5OKkSmcqjL9cBpDEaZrr3ShQlyX2cZ/O/ozE41oxn/Tt0LGEM/w4Rub3A3gw== integrity sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=
dependencies: dependencies:
to-object-path "^0.3.0" to-object-path "^0.3.0"
@ -8505,20 +8418,13 @@ set-value@^2.0.0, set-value@^2.0.1:
is-plain-object "^2.0.3" is-plain-object "^2.0.3"
split-string "^3.0.1" split-string "^3.0.1"
set-value@^3.0.0: set-value@^3.0.0, set-value@^3.0.2:
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/set-value/-/set-value-3.0.2.tgz#74e8ecd023c33d0f77199d415409a40f21e61b90" resolved "https://registry.yarnpkg.com/set-value/-/set-value-3.0.2.tgz#74e8ecd023c33d0f77199d415409a40f21e61b90"
integrity sha512-npjkVoz+ank0zjlV9F47Fdbjfj/PfXyVhZvGALWsyIYU/qrMzpi6avjKW3/7KeSU2Df3I46BrN1xOI1+6vW0hA== integrity sha512-npjkVoz+ank0zjlV9F47Fdbjfj/PfXyVhZvGALWsyIYU/qrMzpi6avjKW3/7KeSU2Df3I46BrN1xOI1+6vW0hA==
dependencies: dependencies:
is-plain-object "^2.0.4" is-plain-object "^2.0.4"
set-value@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/set-value/-/set-value-4.0.1.tgz#bc23522ade2d52314ec3b5d6fb140f5cd3a88acf"
integrity sha512-ayATicCYPVnlNpFmjq2/VmVwhoCQA9+13j8qWp044fmFE3IFphosPtRM+0CJ5xoIx5Uy52fCcwg3XeH2pHbbPQ==
dependencies:
is-plain-object "^2.0.4"
setimmediate@^1.0.4, setimmediate@^1.0.5: setimmediate@^1.0.4, setimmediate@^1.0.5:
version "1.0.5" version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
@ -8816,10 +8722,10 @@ source-map-resolve@^0.6.0:
atob "^2.1.2" atob "^2.1.2"
decode-uri-component "^0.2.0" decode-uri-component "^0.2.0"
source-map-support@^0.5.19, source-map-support@~0.5.12, source-map-support@~0.5.20: source-map-support@^0.5.19, source-map-support@~0.5.12:
version "0.5.21" version "0.5.19"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
dependencies: dependencies:
buffer-from "^1.0.0" buffer-from "^1.0.0"
source-map "^0.6.0" source-map "^0.6.0"
@ -8922,9 +8828,9 @@ ssri@^6.0.1:
figgy-pudding "^3.5.1" figgy-pudding "^3.5.1"
ssri@^8.0.0: ssri@^8.0.0:
version "8.0.1" version "8.0.0"
resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.0.tgz#79ca74e21f8ceaeddfcb4b90143c458b8d988808"
integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== integrity sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==
dependencies: dependencies:
minipass "^3.1.1" minipass "^3.1.1"
@ -9142,11 +9048,6 @@ strip-json-comments@~2.0.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= 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: stylehacks@^4.0.0, stylehacks@^4.0.3:
version "4.0.3" version "4.0.3"
resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5"
@ -9235,14 +9136,14 @@ tapable@^1.0.0, tapable@^1.1.3:
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
tar@^6.0.2: tar@^6.0.2:
version "6.1.11" version "6.0.2"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.2.tgz#5df17813468a6264ff14f766886c622b84ae2f39"
integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== integrity sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==
dependencies: dependencies:
chownr "^2.0.0" chownr "^2.0.0"
fs-minipass "^2.0.0" fs-minipass "^2.0.0"
minipass "^3.0.0" minipass "^3.0.0"
minizlib "^2.1.1" minizlib "^2.1.0"
mkdirp "^1.0.3" mkdirp "^1.0.3"
yallist "^4.0.0" yallist "^4.0.0"
@ -9291,14 +9192,13 @@ terser@^4.1.2:
source-map-support "~0.5.12" source-map-support "~0.5.12"
terser@^5.0.0: terser@^5.0.0:
version "5.14.2" version "5.0.0"
resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" resolved "https://registry.yarnpkg.com/terser/-/terser-5.0.0.tgz#269640e4e92f15d628de1e5f01c4c61e1ba3d765"
integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== integrity sha512-olH2DwGINoSuEpSGd+BsPuAQaA3OrHnHnFL/rDB2TVNc3srUbz/rq/j2BlF4zDXI+JqAvGr86bIm1R2cJgZ3FA==
dependencies: dependencies:
"@jridgewell/source-map" "^0.3.2"
acorn "^8.5.0"
commander "^2.20.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: text-table@^0.2.0:
version "0.2.0" version "0.2.0"
@ -9732,9 +9632,9 @@ url-parse-lax@^3.0.0:
prepend-http "^2.0.0" prepend-http "^2.0.0"
url-parse@^1.4.3, url-parse@^1.4.7: url-parse@^1.4.3, url-parse@^1.4.7:
version "1.5.9" version "1.4.7"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.9.tgz#05ff26484a0b5e4040ac64dcee4177223d74675e" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278"
integrity sha512-HpOvhKBvre8wYez+QhHcYiVvVmeF6DVnuSOOPhe3cTum3BnqHhvKaZm8FU5yTiOu/Jut2ZpB2rA/SbBA1JIGlQ== integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==
dependencies: dependencies:
querystringify "^2.1.1" querystringify "^2.1.1"
requires-port "^1.0.0" requires-port "^1.0.0"
@ -10339,9 +10239,9 @@ ws@^6.2.1:
async-limiter "~1.0.0" async-limiter "~1.0.0"
ws@^7.3.1: ws@^7.3.1:
version "7.4.6" version "7.3.1"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8"
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== integrity sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==
xdg-basedir@^4.0.0: xdg-basedir@^4.0.0:
version "4.0.0" version "4.0.0"
@ -10364,9 +10264,9 @@ xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.1:
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
y18n@^4.0.0: y18n@^4.0.0:
version "4.0.1" version "4.0.0"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
yallist@^2.1.2: yallist@^2.1.2:
version "2.1.2" version "2.1.2"

1
frontend/fonts Symbolic link
View File

@ -0,0 +1 @@
./node_modules/tabler-ui/dist/assets/fonts

View File

@ -1 +0,0 @@
../node_modules/tabler-ui/dist/assets/fonts/feather

View File

@ -20,6 +20,7 @@
<meta name="msapplication-TileColor" content="#333333"> <meta name="msapplication-TileColor" content="#333333">
<meta name="msapplication-config" content="/images/favicons/browserconfig.xml"> <meta name="msapplication-config" content="/images/favicons/browserconfig.xml">
<meta name="theme-color" content="#ffffff"> <meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,300i,400,400i,500,500i,600,600i,700,700i&amp;subset=latin-ext">
<link href="/css/main.css?v=<%= version %>" rel="stylesheet"> <link href="/css/main.css?v=<%= version %>" rel="stylesheet">
</head> </head>
<body> <body>

View File

@ -152,51 +152,6 @@ function FileUpload(path, fd) {
}); });
} }
//ref : https://codepen.io/chrisdpratt/pen/RKxJNo
function DownloadFile(verb, path, filename) {
return new Promise(function (resolve, reject) {
let api_url = '/api/';
let url = api_url + path;
let token = Tokens.getTopToken();
$.ajax({
url: url,
type: verb,
crossDomain: true,
xhrFields: {
withCredentials: true,
responseType: 'blob'
},
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Bearer ' + (token ? token.t : null));
},
success: function (data) {
var a = document.createElement('a');
var url = window.URL.createObjectURL(data);
a.href = url;
a.download = filename;
document.body.append(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
},
error: function (xhr, status, error_thrown) {
let code = 400;
if (typeof xhr.responseJSON !== 'undefined' && typeof xhr.responseJSON.error !== 'undefined' && typeof xhr.responseJSON.error.message !== 'undefined') {
error_thrown = xhr.responseJSON.error.message;
code = xhr.responseJSON.error.code || 500;
}
reject(new ApiError(error_thrown, xhr.responseText, code));
}
});
});
}
module.exports = { module.exports = {
status: function () { status: function () {
return fetch('get', ''); return fetch('get', '');
@ -683,24 +638,6 @@ module.exports = {
*/ */
renew: function (id, timeout = 180000) { renew: function (id, timeout = 180000) {
return fetch('post', 'nginx/certificates/' + id + '/renew', undefined, {timeout}); 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}
*/
download: function (id) {
return DownloadFile('get', "nginx/certificates/" + id + "/download", "certificate.zip")
} }
} }
}, },

View File

@ -2,16 +2,6 @@
<div class="card-status bg-teal"></div> <div class="card-status bg-teal"></div>
<div class="card-header"> <div class="card-header">
<h3 class="card-title"><%- i18n('audit-log', 'title') %></h3> <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>
<div class="card-body no-padding min-100"> <div class="card-body no-padding min-100">
<div class="dimmer active"> <div class="dimmer active">

View File

@ -12,68 +12,39 @@ module.exports = Mn.View.extend({
ui: { ui: {
list_region: '.list-region', list_region: '.list-region',
dimmer: '.dimmer', dimmer: '.dimmer'
search: '.search-form',
query: 'input[name="source-query"]'
},
fetch: App.Api.AuditLog.getAll,
showData: function(response) {
this.showChildView('list_region', new ListView({
collection: new AuditLogModel.Collection(response)
}));
},
showError: function(err) {
this.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showAuditLog();
}
}));
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: { regions: {
list_region: '@ui.list_region' 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 () { onRender: function () {
let view = this; let view = this;
view.fetch(['user']) App.Api.AuditLog.getAll(['user'])
.then(response => { .then(response => {
if (!view.isDestroyed() && response && response.length) { if (!view.isDestroyed() && response && response.length) {
view.showData(response); view.showChildView('list_region', new ListView({
collection: new AuditLogModel.Collection(response)
}));
} else { } else {
view.showEmpty(); view.showChildView('list_region', new EmptyView({
title: App.i18n('audit-log', 'empty'),
subtitle: App.i18n('audit-log', 'empty-subtitle')
}));
} }
}) })
.catch(err => { .catch(err => {
view.showError(err); view.showChildView('list_region', new ErrorView({
code: err.code,
message: err.message,
retry: function () {
App.Controller.showAuditLog();
}
}));
console.error(err);
}) })
.then(() => { .then(() => {
view.ui.dimmer.removeClass('active'); 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 * Audit Log
*/ */

View File

@ -46,12 +46,6 @@
<!-- Authorization --> <!-- Authorization -->
<div class="tab-pane" id="auth"> <div class="tab-pane" id="auth">
<p>
Basic Authorization via
<a target="_blank" href="https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html">
Nginx HTTP Basic Authentication
</a>
</p>
<div class="row"> <div class="row">
<div class="col-sm-6 col-md-6"> <div class="col-sm-6 col-md-6">
<div class="form-group"> <div class="form-group">
@ -66,19 +60,10 @@
</div> </div>
<div class="items"><!-- items --></div> <div class="items"><!-- items --></div>
<div class="btn-list justify-content-end">
<button type="button" class="btn btn-teal auth_add"><%- i18n('access-lists', 'auth-add') %></button>
</div>
</div> </div>
<!-- Access --> <!-- Access -->
<div class="tab-pane" id="access"> <div class="tab-pane" id="access">
<p>
IP Address Whitelist/Blacklist via
<a target="_blank" href="https://nginx.org/en/docs/http/ngx_http_access_module.html">
Nginx HTTP Access
</a>
</p>
<div class="clients"><!-- clients --></div> <div class="clients"><!-- clients --></div>
<div class="row"> <div class="row">
<div class="col-sm-3 col-md-3"> <div class="col-sm-3 col-md-3">
@ -93,9 +78,6 @@
</div> </div>
</div> </div>
<div class="text-muted">Note that the <code>allow</code> and <code>deny</code> directives will be applied in the order they are defined.</div> <div class="text-muted">Note that the <code>allow</code> and <code>deny</code> directives will be applied in the order they are defined.</div>
<div class="btn-list justify-content-end">
<button type="button" class="btn btn-teal access_add"><%- i18n('access-lists', 'access-add') %></button>
</div>
</div> </div>
</div> </div>

View File

@ -25,9 +25,7 @@ module.exports = Mn.View.extend({
form: 'form', form: 'form',
buttons: '.modal-footer button', buttons: '.modal-footer button',
cancel: 'button.cancel', cancel: 'button.cancel',
save: 'button.save', save: 'button.save'
access_add: 'button.access_add',
auth_add: 'button.auth_add'
}, },
regions: { regions: {
@ -107,24 +105,6 @@ module.exports = Mn.View.extend({
alert(err.message); alert(err.message);
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled'); this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
}); });
},
'click @ui.access_add': function (e) {
e.preventDefault();
let clients = this.model.get('clients');
clients.push({});
this.showChildView('clients_region', new ClientsView({
collection: new Backbone.Collection(clients)
}));
},
'click @ui.auth_add': function (e) {
e.preventDefault();
let items = this.model.get('items');
items.push({});
this.showChildView('items_region', new ItemsView({
collection: new Backbone.Collection(items)
}));
} }
}, },
@ -132,9 +112,20 @@ module.exports = Mn.View.extend({
let items = this.model.get('items'); let items = this.model.get('items');
let clients = this.model.get('clients'); let clients = this.model.get('clients');
// Ensure at least one field is shown initally // Add empty items to the end of the list. This is cheating but hey I don't have the time to do it right
if (!items.length) items.push({}); let items_to_add = 5 - items.length;
if (!clients.length) clients.push({}); if (items_to_add) {
for (let i = 0; i < items_to_add; i++) {
items.push({});
}
}
let clients_to_add = 4 - clients.length;
if (clients_to_add) {
for (let i = 0; i < clients_to_add; i++) {
clients.push({});
}
}
this.showChildView('items_region', new ItemsView({ this.showChildView('items_region', new ItemsView({
collection: new Backbone.Collection(items) collection: new Backbone.Collection(items)

View File

@ -8,6 +8,6 @@
</div> </div>
<div class="col-sm-9 col-md-9"> <div class="col-sm-9 col-md-9">
<div class="form-group"> <div class="form-group">
<input type="text" name="address[]" placeholder="IP / Subnet" class="form-control" value="<%- typeof address !== 'undefined' ? address : '' %>" value=""> <input type="text" name="address[]" class="form-control" value="<%- typeof address !== 'undefined' ? address : '' %>" value="">
</div> </div>
</div> </div>

View File

@ -32,7 +32,6 @@
<div class="item-action dropdown"> <div class="item-action dropdown">
<a href="#" data-toggle="dropdown" class="icon"><i class="fe fe-more-vertical"></i></a> <a href="#" data-toggle="dropdown" class="icon"><i class="fe fe-more-vertical"></i></a>
<div class="dropdown-menu dropdown-menu-right"> <div class="dropdown-menu dropdown-menu-right">
<span class="dropdown-header"><%- i18n('audit-log', 'access-list') %> #<%- id %></span>
<a href="#" class="edit dropdown-item"><i class="dropdown-icon fe fe-edit"></i> <%- i18n('str', 'edit') %></a> <a href="#" class="edit dropdown-item"><i class="dropdown-icon fe fe-edit"></i> <%- i18n('str', 'edit') %></a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a href="#" class="delete dropdown-item"><i class="dropdown-icon fe fe-trash-2"></i> <%- i18n('str', 'delete') %></a> <a href="#" class="delete dropdown-item"><i class="dropdown-icon fe fe-trash-2"></i> <%- i18n('str', 'delete') %></a>

View File

@ -3,14 +3,6 @@
<div class="card-header"> <div class="card-header">
<h3 class="card-title"><%- i18n('access-lists', 'title') %></h3> <h3 class="card-title"><%- i18n('access-lists', 'title') %></h3>
<div class="card-options"> <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> <a href="#" class="btn btn-outline-secondary btn-sm ml-2 help"><i class="fe fe-help-circle"></i></a>
<% if (showAddButton) { %> <% if (showAddButton) { %>
<a href="#" class="btn btn-outline-teal btn-sm ml-2 add-item"><%- i18n('access-lists', 'add') %></a> <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', list_region: '.list-region',
add: '.add-item', add: '.add-item',
help: '.help', help: '.help',
dimmer: '.dimmer', 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();
}
}));
}, },
regions: { regions: {
@ -67,17 +30,6 @@ module.exports = Mn.View.extend({
'click @ui.help': function (e) { 'click @ui.help': function (e) {
e.preventDefault(); e.preventDefault();
App.Controller.showHelp(App.i18n('access-lists', 'help-title'), App.i18n('access-lists', 'help-content')); 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 () { onRender: function () {
let view = this; let view = this;
view.fetch(['owner', 'items', 'clients']) App.Api.Nginx.AccessLists.getAll(['owner', 'items', 'clients'])
.then(response => { .then(response => {
if (!view.isDestroyed()) { if (!view.isDestroyed()) {
if (response && response.length) { if (response && response.length) {
view.showData(response); view.showChildView('list_region', new ListView({
collection: new AccessListModel.Collection(response)
}));
} else { } 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 => { .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(() => { .then(() => {
view.ui.dimmer.removeClass('active'); view.ui.dimmer.removeClass('active');

View File

@ -16,8 +16,6 @@ module.exports = Mn.View.extend({
events: { events: {
'click @ui.save': function (e) { 'click @ui.save': function (e) {
e.preventDefault(); e.preventDefault();
this.ui.save.addClass('btn-loading');
this.ui.buttons.prop('disabled', true).addClass('btn-disabled');
App.Api.Nginx.Certificates.delete(this.model.get('id')) App.Api.Nginx.Certificates.delete(this.model.get('id'))
.then(() => { .then(() => {
@ -27,7 +25,6 @@ module.exports = Mn.View.extend({
.catch(err => { .catch(err => {
alert(err.message); alert(err.message);
this.ui.buttons.prop('disabled', false).removeClass('btn-disabled'); this.ui.buttons.prop('disabled', false).removeClass('btn-disabled');
this.ui.save.removeClass('btn-loading');
}); });
} }
} }

View File

@ -18,14 +18,6 @@
<input type="text" name="domain_names" class="form-control" id="input-domains" value="<%- domain_names.join(',') %>" required> <input type="text" name="domain_names" class="form-control" id="input-domains" value="<%- domain_names.join(',') %>" required>
<div class="text-blue"><i class="fe fe-alert-triangle"></i> <%- i18n('ssl', 'hosts-warning') %></div> <div class="text-blue"><i class="fe fe-alert-triangle"></i> <%- i18n('ssl', 'hosts-warning') %></div>
</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>
<div class="col-sm-12 col-md-12"> <div class="col-sm-12 col-md-12">
<div class="form-group"> <div class="form-group">
@ -137,9 +129,6 @@
</div> </div>
<% } else if (provider === 'other') { %> <% } else if (provider === 'other') { %>
<!-- Other --> <!-- Other -->
<div class="col-sm-12 col-md-12">
<div class="text-blue mb-4"><i class="fe fe-alert-triangle"></i> <%= i18n('ssl', 'passphrase-protection-support-info') %></div>
</div>
<div class="col-sm-12 col-md-12"> <div class="col-sm-12 col-md-12">
<div class="form-group"> <div class="form-group">
<label class="form-label"><%- i18n('str', 'name') %> <span class="form-required">*</span></label> <label class="form-label"><%- i18n('str', 'name') %> <span class="form-required">*</span></label>

View File

@ -4,20 +4,11 @@ const App = require('../../main');
const CertificateModel = require('../../../models/certificate'); const CertificateModel = require('../../../models/certificate');
const template = require('./form.ejs'); const template = require('./form.ejs');
const i18n = require('../../i18n'); const i18n = require('../../i18n');
const dns_providers = sortProvidersAlphabetically(require('../../../../../global/certbot-dns-plugins')); const dns_providers = require('../../../../../global/certbot-dns-plugins');
require('jquery-serializejson'); require('jquery-serializejson');
require('selectize'); require('selectize');
function sortProvidersAlphabetically(obj) {
return Object.entries(obj)
.sort((a,b) => a[1].display_name.toLowerCase() > b[1].display_name.toLowerCase())
.reduce((result, entry) => {
result[entry[0]] = entry[1];
return result;
}, {});
}
module.exports = Mn.View.extend({ module.exports = Mn.View.extend({
template: template, template: template,
className: 'modal-dialog', className: 'modal-dialog',
@ -29,8 +20,6 @@ module.exports = Mn.View.extend({
non_loader_content: '.non-loader-content', non_loader_content: '.non-loader-content',
le_error_info: '#le-error-info', le_error_info: '#le-error-info',
domain_names: 'input[name="domain_names"]', domain_names: 'input[name="domain_names"]',
test_domains_container: '.test-domains-container',
test_domains_button: '.test-domains',
buttons: '.modal-footer button', buttons: '.modal-footer button',
cancel: 'button.cancel', cancel: 'button.cancel',
save: 'button.save', save: 'button.save',
@ -58,12 +47,10 @@ module.exports = Mn.View.extend({
this.ui.dns_provider_credentials.prop('required', 'required'); this.ui.dns_provider_credentials.prop('required', 'required');
} }
this.ui.dns_challenge_content.show(); this.ui.dns_challenge_content.show();
this.ui.test_domains_container.hide();
} else { } else {
this.ui.dns_provider.prop('required', false); this.ui.dns_provider.prop('required', false);
this.ui.dns_provider_credentials.prop('required', false); this.ui.dns_provider_credentials.prop('required', false);
this.ui.dns_challenge_content.hide(); this.ui.dns_challenge_content.hide();
this.ui.test_domains_container.show();
} }
}, },
@ -209,23 +196,6 @@ module.exports = Mn.View.extend({
this.ui.non_loader_content.show(); 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){ 'change @ui.other_certificate_key': function(e){
this.setFileName("other_certificate_key_label", e) this.setFileName("other_certificate_key_label", e)
}, },
@ -272,18 +242,12 @@ module.exports = Mn.View.extend({
text: input text: input
}; };
}, },
createFilter: /^(?:\*\.)?(?:[^.*]+\.?)+[^.]$/ createFilter: /^(?:[^.]+\.?)+[^.]$/
}); });
this.ui.dns_challenge_content.hide(); this.ui.dns_challenge_content.hide();
this.ui.credentials_file_content.hide(); this.ui.credentials_file_content.hide();
this.ui.loader_content.hide(); this.ui.loader_content.hide();
this.ui.le_error_info.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) { initialize: function (options) {

View File

@ -38,13 +38,8 @@
<div class="item-action dropdown"> <div class="item-action dropdown">
<a href="#" data-toggle="dropdown" class="icon"><i class="fe fe-more-vertical"></i></a> <a href="#" data-toggle="dropdown" class="icon"><i class="fe fe-more-vertical"></i></a>
<div class="dropdown-menu dropdown-menu-right"> <div class="dropdown-menu dropdown-menu-right">
<span class="dropdown-header"><%- i18n('audit-log', 'certificate') %> #<%- id %></span>
<% if (provider === 'letsencrypt') { %> <% 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="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> <div class="dropdown-divider"></div>
<% } %> <% } %>
<a href="#" class="delete dropdown-item"><i class="dropdown-icon fe fe-trash-2"></i> <%- i18n('str', 'delete') %></a> <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 moment = require('moment');
const App = require('../../../main'); const App = require('../../../main');
const template = require('./item.ejs'); const template = require('./item.ejs');
const dns_providers = require('../../../../../../global/certbot-dns-plugins'); const dns_providers = require('../../../../../../global/certbot-dns-plugins')
module.exports = Mn.View.extend({ module.exports = Mn.View.extend({
template: template, template: template,
@ -11,9 +11,7 @@ module.exports = Mn.View.extend({
ui: { ui: {
host_link: '.host-link', host_link: '.host-link',
renew: 'a.renew', renew: 'a.renew',
delete: 'a.delete', delete: 'a.delete'
download: 'a.download',
test: 'a.test'
}, },
events: { events: {
@ -31,17 +29,7 @@ module.exports = Mn.View.extend({
e.preventDefault(); e.preventDefault();
let win = window.open($(e.currentTarget).attr('rel'), '_blank'); let win = window.open($(e.currentTarget).attr('rel'), '_blank');
win.focus(); win.focus();
}, }
'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);
},
}, },
templateContext: { templateContext: {

View File

@ -3,14 +3,6 @@
<div class="card-header"> <div class="card-header">
<h3 class="card-title"><%- i18n('certificates', 'title') %></h3> <h3 class="card-title"><%- i18n('certificates', 'title') %></h3>
<div class="card-options"> <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> <a href="#" class="btn btn-outline-secondary btn-sm ml-2 help"><i class="fe fe-help-circle"></i></a>
<% if (showAddButton) { %> <% if (showAddButton) { %>
<div class="dropdown"> <div class="dropdown">

View File

@ -14,44 +14,7 @@ module.exports = Mn.View.extend({
list_region: '.list-region', list_region: '.list-region',
add: '.add-item', add: '.add-item',
help: '.help', help: '.help',
dimmer: '.dimmer', 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();
}
}));
}, },
regions: { regions: {
@ -68,17 +31,6 @@ module.exports = Mn.View.extend({
'click @ui.help': function (e) { 'click @ui.help': function (e) {
e.preventDefault(); e.preventDefault();
App.Controller.showHelp(App.i18n('certificates', 'help-title'), App.i18n('certificates', 'help-content')); 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 () { onRender: function () {
let view = this; let view = this;
view.fetch(['owner']) App.Api.Nginx.Certificates.getAll(['owner'])
.then(response => { .then(response => {
if (!view.isDestroyed()) { if (!view.isDestroyed()) {
if (response && response.length) { if (response && response.length) {
view.showData(response); view.showChildView('list_region', new ListView({
collection: new CertificateModel.Collection(response)
}));
} else { } 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 => { .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(() => { .then(() => {
view.ui.dimmer.removeClass('active'); 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> <form>
<div class="row"> <div class="row">
<div class="col-sm-12 col-md-12"> <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) { %> <% if (certificate_id) { %>
<br><br> <br><br>
<%- i18n('ssl', 'delete-ssl') %> <%- i18n('ssl', 'delete-ssl') %>

Some files were not shown because too many files have changed in this diff Show More