Compare commits
187 Commits
v2.9.4
...
official-d
Author | SHA1 | Date | |
---|---|---|---|
747de511d4 | |||
adc5a2020a | |||
40b1521f72 | |||
ac23c66659 | |||
6392df36c3 | |||
c82843279c | |||
b394eb8e55 | |||
bb422d4454 | |||
d45f39aae3 | |||
cb091040a8 | |||
ddd538944a | |||
1f879f67a9 | |||
ee89dedd0f | |||
9ab5333652 | |||
3bd97ae1b0 | |||
432062e0f4 | |||
0c8bbb4bc2 | |||
48e96c46d5 | |||
25e9acf618 | |||
a517e80236 | |||
3d4d3bc73b | |||
cf4d1f73fa | |||
c203d1a0d8 | |||
5f29f6b039 | |||
f75b5b867b | |||
67463ca136 | |||
8db541f37f | |||
a5229d0e92 | |||
38ec0f9f95 | |||
3d80759a21 | |||
d95cd36b3e | |||
4c6b96ad5d | |||
c3bef2867e | |||
efc5bff2e1 | |||
ffe3db8c08 | |||
4ada0feae3 | |||
e17de6058e | |||
9efe6cfb39 | |||
c86a1a50bd | |||
c55476b196 | |||
3b47decbb0 | |||
d0bfa082e0 | |||
6b7a8b009e | |||
ca59e585d8 | |||
bbde7a108a | |||
87731a8b5c | |||
29d4bd4ccf | |||
925ad90f91 | |||
650ae61c43 | |||
02f3f9704f | |||
da7c3057b4 | |||
040b45cafa | |||
8ece310b9f | |||
96959db3c2 | |||
6360100611 | |||
b833044cea | |||
97909830f5 | |||
8ae2de2f49 | |||
bf7b659e89 | |||
4e3c7749af | |||
f63441921f | |||
725ba83606 | |||
281906c0b5 | |||
8ed121f43d | |||
81a9cab2b3 | |||
8d98a417c5 | |||
6fa81b179b | |||
9e169fbb42 | |||
27f84f880a | |||
0d9c941b4e | |||
8865aa9c8c | |||
6d8c4218f1 | |||
c134a43337 | |||
780759dc27 | |||
85128f08f3 | |||
d2f8c1e5f1 | |||
9c88b9c1e9 | |||
13fd2ce4e2 | |||
9979f516d6 | |||
39a5cd2d6e | |||
784516283f | |||
ce503232c3 | |||
f2edf9130f | |||
413ab50fc4 | |||
c1880bd3ff | |||
0f0a672275 | |||
06c5f991e7 | |||
babc5b7a38 | |||
b96c996a45 | |||
fb8f2c2f9a | |||
6794937391 | |||
f022e84979 | |||
fd5ac952cc | |||
07f60e5c77 | |||
628b8a7e1f | |||
30a442807d | |||
1626c8edd1 | |||
ca6561bf6c | |||
273a81471d | |||
8b07a67133 | |||
32089ea272 | |||
658acd147c | |||
ca3370a6ac | |||
c4e2557de2 | |||
6f2b4fdf86 | |||
f302ff71c9 | |||
fee87a44d6 | |||
8944609b63 | |||
be87c45f27 | |||
1b1807c79a | |||
a8f4699816 | |||
ac3df6dd77 | |||
5c67908460 | |||
7b67ef3015 | |||
e5a3b5ee2f | |||
5e9ff4d2bf | |||
daa71764b6 | |||
6a6c2ef192 | |||
320315956d | |||
4f10d129c2 | |||
62eb3fcd85 | |||
ab40e4e2cf | |||
0bb9450642 | |||
a6e15532b9 | |||
9a89a8a77e | |||
fe3675dc7a | |||
5c9acc2bff | |||
c94e937a50 | |||
3e4e10e644 | |||
ba7bb57ca2 | |||
14c125150a | |||
053701a702 | |||
3fc3e43042 | |||
b0dc68d7d4 | |||
e895baaeb4 | |||
c47f6fdb21 | |||
9e188e441a | |||
f6efcdf9f9 | |||
b1ceda3af4 | |||
cd3a0684d0 | |||
f25e54c6cb | |||
66f86cf497 | |||
d260edc547 | |||
ba1e6fa984 | |||
6b59f36213 | |||
1894960762 | |||
83c5c55f32 | |||
fb8c0b9a48 | |||
d34691152c | |||
cea80b482e | |||
c460a8fa5c | |||
5f852437fe | |||
8aded1a685 | |||
f2acb9e150 | |||
6f3a00c9b8 | |||
fbae107c04 | |||
6c1ae77a2a | |||
67e8ca6714 | |||
a56d976947 | |||
ac0bb6bee2 | |||
dee67dac75 | |||
9458cfbd1a | |||
4b8bdd22b3 | |||
a4c143e2d1 | |||
e91019feb9 | |||
8a37ec72b7 | |||
c263a33095 | |||
4b2c0115db | |||
673f40bd85 | |||
b9f8108cd3 | |||
a16ecf656b | |||
842cff130b | |||
346b9b4b79 | |||
56c317d223 | |||
b7b150a979 | |||
fae848bd1b | |||
a5b8087dc5 | |||
7aa078e025 | |||
4b6b276b64 | |||
bd3a13b2a5 | |||
289d179142 | |||
deca493912 | |||
d16bf7d6c0 | |||
56c4f8a106 | |||
99ef8bae4c | |||
92eec95dad | |||
389fd158ad |
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -68,7 +68,7 @@ pipeline {
|
||||
-v "$(pwd)/global:/app/global" \\
|
||||
-w /app \\
|
||||
node:latest \\
|
||||
sh -c "yarn install && yarn eslint . && rm -rf node_modules"
|
||||
sh -c "ln -s /usr/bin/python3 /usr/bin/python && yarn install && yarn eslint . && rm -rf node_modules"
|
||||
'''
|
||||
|
||||
echo 'Docker Build ...'
|
||||
|
115
README.md
115
README.md
@ -1,7 +1,7 @@
|
||||
<p align="center">
|
||||
<img src="https://nginxproxymanager.com/github.png">
|
||||
<br><br>
|
||||
<img src="https://img.shields.io/badge/version-2.9.4-green.svg?style=for-the-badge">
|
||||
<img src="https://img.shields.io/badge/version-2.9.13-green.svg?style=for-the-badge">
|
||||
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
|
||||
<img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge">
|
||||
</a>
|
||||
@ -17,7 +17,6 @@
|
||||
<a href="https://reddit.com/r/nginxproxymanager">
|
||||
<img alt="Reddit" src="https://img.shields.io/reddit/subreddit-subscribers/nginxproxymanager?label=Reddit%20Community&style=for-the-badge">
|
||||
</a>
|
||||
|
||||
</p>
|
||||
|
||||
This project comes as a pre-built docker image that enables you to easily forward to your websites
|
||||
@ -75,28 +74,12 @@ services:
|
||||
- '80:80'
|
||||
- '81:81'
|
||||
- '443:443'
|
||||
environment:
|
||||
DB_MYSQL_HOST: "db"
|
||||
DB_MYSQL_PORT: 3306
|
||||
DB_MYSQL_USER: "npm"
|
||||
DB_MYSQL_PASSWORD: "npm"
|
||||
DB_MYSQL_NAME: "npm"
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./letsencrypt:/etc/letsencrypt
|
||||
db:
|
||||
image: 'jc21/mariadb-aria:latest'
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: 'npm'
|
||||
MYSQL_DATABASE: 'npm'
|
||||
MYSQL_USER: 'npm'
|
||||
MYSQL_PASSWORD: 'npm'
|
||||
volumes:
|
||||
- ./data/mysql:/var/lib/mysql
|
||||
```
|
||||
|
||||
3. Bring up your stack
|
||||
3. Bring up your stack by running
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
@ -414,6 +397,100 @@ Special thanks to the following contributors:
|
||||
<br /><sub><b>RBXII3</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/demize">
|
||||
<img src="https://avatars.githubusercontent.com/u/264914?v=4" width="80" alt=""/>
|
||||
<br /><sub><b>demize</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/PUP-Loki">
|
||||
<img src="https://avatars.githubusercontent.com/u/75944209?v=4" width="80" alt=""/>
|
||||
<br /><sub><b>PUP-Loki</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/DSorlov">
|
||||
<img src="https://avatars.githubusercontent.com/u/8133650?v=4" width="80" alt=""/>
|
||||
<br /><sub><b>Daniel Sörlöv</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Theyooo">
|
||||
<img src="https://avatars.githubusercontent.com/u/58510131?v=4" width="80" alt=""/>
|
||||
<br /><sub><b>Theyooo</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/mrdink">
|
||||
<img src="https://avatars.githubusercontent.com/u/514751?v=4" width="80" alt=""/>
|
||||
<br /><sub><b>Justin Peacock</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/ChrisTracy">
|
||||
<img src="https://avatars.githubusercontent.com/u/58871574?v=4" width="80" alt=""/>
|
||||
<br /><sub><b>Chris Tracy</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Fuechslein">
|
||||
<img src="https://avatars.githubusercontent.com/u/15112818?v=4" width="80" alt=""/>
|
||||
<br /><sub><b>Fuechslein</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/nightah">
|
||||
<img src="https://avatars.githubusercontent.com/u/3339418?v=4" width="80" alt=""/>
|
||||
<br /><sub><b>Amir Zarrinkafsh</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/gabbe">
|
||||
<img src="https://avatars.githubusercontent.com/u/156397?v=4" width="80" alt=""/>
|
||||
<br /><sub><b>gabbe</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bmbvenom">
|
||||
<img src="https://avatars.githubusercontent.com/u/20530371?v=4" width="80" alt=""/>
|
||||
<br /><sub><b>bmbvenom</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/FMeinicke">
|
||||
<img src="https://avatars.githubusercontent.com/u/42121639?v=4" width="80" alt=""/>
|
||||
<br /><sub><b>Florian Meinicke</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/ssrahul96">
|
||||
<img src="https://avatars.githubusercontent.com/u/15570570?v=4" width="80" alt=""/>
|
||||
<br /><sub><b>Rahul Somasundaram</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/BjoernAkAManf">
|
||||
<img src="https://avatars.githubusercontent.com/u/833043?v=4" width="80" alt=""/>
|
||||
<br /><sub><b>Björn Heinrichs</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/realJoshByrnes">
|
||||
<img src="https://avatars.githubusercontent.com/u/204185?v=4" width="80" alt=""/>
|
||||
<br /><sub><b>Josh Byrnes</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bergi9">
|
||||
<img src="https://avatars.githubusercontent.com/u/5556750?v=4" width="80" alt=""/>
|
||||
<br /><sub><b>bergi9</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- markdownlint-enable -->
|
||||
|
@ -40,13 +40,12 @@ app.use(function (req, res, next) {
|
||||
}
|
||||
|
||||
res.set({
|
||||
'Strict-Transport-Security': 'includeSubDomains; max-age=631138519; preload',
|
||||
'X-XSS-Protection': '1; mode=block',
|
||||
'X-Content-Type-Options': 'nosniff',
|
||||
'X-Frame-Options': x_frame_options,
|
||||
'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
|
||||
Pragma: 'no-cache',
|
||||
Expires: 0
|
||||
'X-XSS-Protection': '1; mode=block',
|
||||
'X-Content-Type-Options': 'nosniff',
|
||||
'X-Frame-Options': x_frame_options,
|
||||
'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
|
||||
Pragma: 'no-cache',
|
||||
Expires: 0
|
||||
});
|
||||
next();
|
||||
});
|
||||
@ -75,7 +74,7 @@ app.use(function (err, req, res, next) {
|
||||
|
||||
// Not every error is worth logging - but this is good for now until it gets annoying.
|
||||
if (typeof err.stack !== 'undefined' && err.stack) {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
if (process.env.NODE_ENV === 'development' || process.env.DEBUG) {
|
||||
log.debug(err.stack);
|
||||
} else if (typeof err.public == 'undefined' || !err.public) {
|
||||
log.warn(err.message);
|
||||
|
133
backend/index.js
133
backend/index.js
@ -44,84 +44,85 @@ 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;
|
||||
const envSqliteFile = process.env.DB_SQLITE_FILE || null;
|
||||
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;
|
||||
|
||||
if ((envMysqlHost && envMysqlPort && envMysqlUser && envMysqlName) || envSqliteFile) {
|
||||
const fs = require('fs');
|
||||
const filename = (process.env.NODE_CONFIG_DIR || './config') + '/' + (process.env.NODE_ENV || 'default') + '.json';
|
||||
let configData = {};
|
||||
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
|
||||
}
|
||||
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');
|
||||
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;
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
logger.info('Generating MySQL knex configuration from environment variables');
|
||||
configData.database = newConfig;
|
||||
|
||||
if (JSON.stringify(configData.database) === JSON.stringify(newConfig)) {
|
||||
// Config is unchanged, skip overwrite
|
||||
resolve();
|
||||
return;
|
||||
} else {
|
||||
const newConfig = {
|
||||
fromEnv: true,
|
||||
engine: 'knex-native',
|
||||
knex: {
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: envSqliteFile
|
||||
},
|
||||
useNullAsDefault: true
|
||||
}
|
||||
|
||||
logger.info('Generating MySQL db configuration from environment variables');
|
||||
configData.database = newConfig;
|
||||
|
||||
} else {
|
||||
const newConfig = {
|
||||
fromEnv: true,
|
||||
engine: 'knex-native',
|
||||
knex: {
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: envSqliteFile
|
||||
},
|
||||
useNullAsDefault: true
|
||||
}
|
||||
};
|
||||
if (JSON.stringify(configData.database) === JSON.stringify(newConfig)) {
|
||||
// Config is unchanged, skip overwrite
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info('Generating Sqlite db configuration from environment variables');
|
||||
configData.database = newConfig;
|
||||
};
|
||||
if (JSON.stringify(configData.database) === JSON.stringify(newConfig)) {
|
||||
// Config is unchanged, skip overwrite
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
// Write config
|
||||
fs.writeFile(filename, JSON.stringify(configData, null, 2), (err) => {
|
||||
if (err) {
|
||||
logger.error('Could not write db config to config file: ' + filename);
|
||||
reject(err);
|
||||
} else {
|
||||
logger.info('Wrote db configuration to config file: ' + filename);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
resolve();
|
||||
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();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,6 @@ const internalAccessList = {
|
||||
// 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);
|
||||
}
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
// patch name if specified
|
||||
@ -205,6 +204,7 @@ const internalAccessList = {
|
||||
});
|
||||
}
|
||||
})
|
||||
.then(internalNginx.reload)
|
||||
.then(() => {
|
||||
// Add to audit log
|
||||
return internalAuditLog.add(access, {
|
||||
|
@ -1,19 +1,22 @@
|
||||
const fs = require('fs');
|
||||
const _ = require('lodash');
|
||||
const logger = require('../logger').ssl;
|
||||
const error = require('../lib/error');
|
||||
const certificateModel = require('../models/certificate');
|
||||
const internalAuditLog = require('./audit-log');
|
||||
const tempWrite = require('temp-write');
|
||||
const utils = require('../lib/utils');
|
||||
const moment = require('moment');
|
||||
const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG;
|
||||
const le_staging = process.env.NODE_ENV !== 'production';
|
||||
const internalNginx = require('./nginx');
|
||||
const internalHost = require('./host');
|
||||
const certbot_command = 'certbot';
|
||||
const le_config = '/etc/letsencrypt.ini';
|
||||
const dns_plugins = require('../global/certbot-dns-plugins');
|
||||
const _ = require('lodash');
|
||||
const fs = require('fs');
|
||||
const https = require('https');
|
||||
const tempWrite = require('temp-write');
|
||||
const moment = require('moment');
|
||||
const logger = require('../logger').ssl;
|
||||
const error = require('../lib/error');
|
||||
const utils = require('../lib/utils');
|
||||
const certificateModel = require('../models/certificate');
|
||||
const dnsPlugins = require('../global/certbot-dns-plugins');
|
||||
const internalAuditLog = require('./audit-log');
|
||||
const internalNginx = require('./nginx');
|
||||
const internalHost = require('./host');
|
||||
const letsencryptStaging = process.env.NODE_ENV !== 'production';
|
||||
const letsencryptConfig = '/etc/letsencrypt.ini';
|
||||
const certbotCommand = 'certbot';
|
||||
const archiver = require('archiver');
|
||||
const path = require('path');
|
||||
const { isArray } = require('lodash');
|
||||
|
||||
function omissions() {
|
||||
return ['is_deleted'];
|
||||
@ -21,14 +24,14 @@ function omissions() {
|
||||
|
||||
const internalCertificate = {
|
||||
|
||||
allowed_ssl_files: ['certificate', 'certificate_key', 'intermediate_certificate'],
|
||||
interval_timeout: 1000 * 60 * 60, // 1 hour
|
||||
interval: null,
|
||||
interval_processing: false,
|
||||
allowedSslFiles: ['certificate', 'certificate_key', 'intermediate_certificate'],
|
||||
intervalTimeout: 1000 * 60 * 60, // 1 hour
|
||||
interval: null,
|
||||
intervalProcessing: false,
|
||||
|
||||
initTimer: () => {
|
||||
logger.info('Let\'s Encrypt Renewal Timer initialized');
|
||||
internalCertificate.interval = setInterval(internalCertificate.processExpiringHosts, internalCertificate.interval_timeout);
|
||||
internalCertificate.interval = setInterval(internalCertificate.processExpiringHosts, internalCertificate.intervalTimeout);
|
||||
// And do this now as well
|
||||
internalCertificate.processExpiringHosts();
|
||||
},
|
||||
@ -37,15 +40,15 @@ const internalCertificate = {
|
||||
* Triggered by a timer, this will check for expiring hosts and renew their ssl certs if required
|
||||
*/
|
||||
processExpiringHosts: () => {
|
||||
if (!internalCertificate.interval_processing) {
|
||||
internalCertificate.interval_processing = true;
|
||||
if (!internalCertificate.intervalProcessing) {
|
||||
internalCertificate.intervalProcessing = true;
|
||||
logger.info('Renewing SSL certs close to expiry...');
|
||||
|
||||
let cmd = certbot_command + ' renew --non-interactive --quiet ' +
|
||||
'--config "' + le_config + '" ' +
|
||||
const cmd = certbotCommand + ' renew --non-interactive --quiet ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
'--preferred-challenges "dns,http" ' +
|
||||
'--disable-hook-validation ' +
|
||||
(le_staging ? '--staging' : '');
|
||||
(letsencryptStaging ? '--staging' : '');
|
||||
|
||||
return utils.exec(cmd)
|
||||
.then((result) => {
|
||||
@ -93,11 +96,11 @@ const internalCertificate = {
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
internalCertificate.interval_processing = false;
|
||||
internalCertificate.intervalProcessing = false;
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error(err);
|
||||
internalCertificate.interval_processing = false;
|
||||
internalCertificate.intervalProcessing = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
@ -113,7 +116,7 @@ const internalCertificate = {
|
||||
data.owner_user_id = access.token.getUserId(1);
|
||||
|
||||
if (data.provider === 'letsencrypt') {
|
||||
data.nice_name = data.domain_names.sort().join(', ');
|
||||
data.nice_name = data.domain_names.join(', ');
|
||||
}
|
||||
|
||||
return certificateModel
|
||||
@ -221,7 +224,7 @@ const internalCertificate = {
|
||||
await certificateModel
|
||||
.query()
|
||||
.deleteById(certificate.id);
|
||||
|
||||
|
||||
throw error;
|
||||
});
|
||||
} else {
|
||||
@ -336,6 +339,71 @@ 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 {Object} data
|
||||
@ -448,11 +516,9 @@ const internalCertificate = {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
writeCustomCert: (certificate) => {
|
||||
if (debug_mode) {
|
||||
logger.info('Writing Custom Certificate:', certificate);
|
||||
}
|
||||
logger.info('Writing Custom Certificate:', certificate);
|
||||
|
||||
let dir = '/data/custom_ssl/npm-' + certificate.id;
|
||||
const dir = '/data/custom_ssl/npm-' + certificate.id;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (certificate.provider === 'letsencrypt') {
|
||||
@ -460,9 +526,9 @@ const internalCertificate = {
|
||||
return;
|
||||
}
|
||||
|
||||
let cert_data = certificate.meta.certificate;
|
||||
let certData = certificate.meta.certificate;
|
||||
if (typeof certificate.meta.intermediate_certificate !== 'undefined') {
|
||||
cert_data = cert_data + '\n' + certificate.meta.intermediate_certificate;
|
||||
certData = certData + '\n' + certificate.meta.intermediate_certificate;
|
||||
}
|
||||
|
||||
try {
|
||||
@ -474,7 +540,7 @@ const internalCertificate = {
|
||||
return;
|
||||
}
|
||||
|
||||
fs.writeFile(dir + '/fullchain.pem', cert_data, function (err) {
|
||||
fs.writeFile(dir + '/fullchain.pem', certData, function (err) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
@ -524,7 +590,7 @@ const internalCertificate = {
|
||||
// Put file contents into an object
|
||||
let files = {};
|
||||
_.map(data.files, (file, name) => {
|
||||
if (internalCertificate.allowed_ssl_files.indexOf(name) !== -1) {
|
||||
if (internalCertificate.allowedSslFiles.indexOf(name) !== -1) {
|
||||
files[name] = file.data.toString();
|
||||
}
|
||||
});
|
||||
@ -582,7 +648,7 @@ const internalCertificate = {
|
||||
}
|
||||
|
||||
_.map(data.files, (file, name) => {
|
||||
if (internalCertificate.allowed_ssl_files.indexOf(name) !== -1) {
|
||||
if (internalCertificate.allowedSslFiles.indexOf(name) !== -1) {
|
||||
row.meta[name] = file.data.toString();
|
||||
}
|
||||
});
|
||||
@ -601,7 +667,7 @@ const internalCertificate = {
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
return _.pick(row.meta, internalCertificate.allowed_ssl_files);
|
||||
return _.pick(row.meta, internalCertificate.allowedSslFiles);
|
||||
});
|
||||
});
|
||||
},
|
||||
@ -649,9 +715,9 @@ const internalCertificate = {
|
||||
return tempWrite(certificate, '/tmp')
|
||||
.then((filepath) => {
|
||||
return internalCertificate.getCertificateInfoFromFile(filepath, throw_expired)
|
||||
.then((cert_data) => {
|
||||
.then((certData) => {
|
||||
fs.unlinkSync(filepath);
|
||||
return cert_data;
|
||||
return certData;
|
||||
}).catch((err) => {
|
||||
fs.unlinkSync(filepath);
|
||||
throw err;
|
||||
@ -667,33 +733,33 @@ const internalCertificate = {
|
||||
* @param {Boolean} [throw_expired] Throw when the certificate is out of date
|
||||
*/
|
||||
getCertificateInfoFromFile: (certificate_file, throw_expired) => {
|
||||
let cert_data = {};
|
||||
let certData = {};
|
||||
|
||||
return utils.exec('openssl x509 -in ' + certificate_file + ' -subject -noout')
|
||||
.then((result) => {
|
||||
// subject=CN = something.example.com
|
||||
let regex = /(?:subject=)?[^=]+=\s+(\S+)/gim;
|
||||
let match = regex.exec(result);
|
||||
const regex = /(?:subject=)?[^=]+=\s+(\S+)/gim;
|
||||
const match = regex.exec(result);
|
||||
|
||||
if (typeof match[1] === 'undefined') {
|
||||
throw new error.ValidationError('Could not determine subject from certificate: ' + result);
|
||||
}
|
||||
|
||||
cert_data['cn'] = match[1];
|
||||
certData['cn'] = match[1];
|
||||
})
|
||||
.then(() => {
|
||||
return utils.exec('openssl x509 -in ' + certificate_file + ' -issuer -noout');
|
||||
})
|
||||
.then((result) => {
|
||||
// issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
|
||||
let regex = /^(?:issuer=)?(.*)$/gim;
|
||||
let match = regex.exec(result);
|
||||
const regex = /^(?:issuer=)?(.*)$/gim;
|
||||
const match = regex.exec(result);
|
||||
|
||||
if (typeof match[1] === 'undefined') {
|
||||
throw new error.ValidationError('Could not determine issuer from certificate: ' + result);
|
||||
}
|
||||
|
||||
cert_data['issuer'] = match[1];
|
||||
certData['issuer'] = match[1];
|
||||
})
|
||||
.then(() => {
|
||||
return utils.exec('openssl x509 -in ' + certificate_file + ' -dates -noout');
|
||||
@ -701,39 +767,39 @@ const internalCertificate = {
|
||||
.then((result) => {
|
||||
// notBefore=Jul 14 04:04:29 2018 GMT
|
||||
// notAfter=Oct 12 04:04:29 2018 GMT
|
||||
let valid_from = null;
|
||||
let valid_to = null;
|
||||
let validFrom = null;
|
||||
let validTo = null;
|
||||
|
||||
let lines = result.split('\n');
|
||||
const lines = result.split('\n');
|
||||
lines.map(function (str) {
|
||||
let regex = /^(\S+)=(.*)$/gim;
|
||||
let match = regex.exec(str.trim());
|
||||
const regex = /^(\S+)=(.*)$/gim;
|
||||
const match = regex.exec(str.trim());
|
||||
|
||||
if (match && typeof match[2] !== 'undefined') {
|
||||
let date = parseInt(moment(match[2], 'MMM DD HH:mm:ss YYYY z').format('X'), 10);
|
||||
const date = parseInt(moment(match[2], 'MMM DD HH:mm:ss YYYY z').format('X'), 10);
|
||||
|
||||
if (match[1].toLowerCase() === 'notbefore') {
|
||||
valid_from = date;
|
||||
validFrom = date;
|
||||
} else if (match[1].toLowerCase() === 'notafter') {
|
||||
valid_to = date;
|
||||
validTo = date;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!valid_from || !valid_to) {
|
||||
if (!validFrom || !validTo) {
|
||||
throw new error.ValidationError('Could not determine dates from certificate: ' + result);
|
||||
}
|
||||
|
||||
if (throw_expired && valid_to < parseInt(moment().format('X'), 10)) {
|
||||
if (throw_expired && validTo < parseInt(moment().format('X'), 10)) {
|
||||
throw new error.ValidationError('Certificate has expired');
|
||||
}
|
||||
|
||||
cert_data['dates'] = {
|
||||
from: valid_from,
|
||||
to: valid_to
|
||||
certData['dates'] = {
|
||||
from: validFrom,
|
||||
to: validTo
|
||||
};
|
||||
|
||||
return cert_data;
|
||||
return certData;
|
||||
}).catch((err) => {
|
||||
throw new error.ValidationError('Certificate is not valid (' + err.message + ')', err);
|
||||
});
|
||||
@ -747,7 +813,7 @@ const internalCertificate = {
|
||||
* @returns {Object}
|
||||
*/
|
||||
cleanMeta: function (meta, remove) {
|
||||
internalCertificate.allowed_ssl_files.map((key) => {
|
||||
internalCertificate.allowedSslFiles.map((key) => {
|
||||
if (typeof meta[key] !== 'undefined' && meta[key]) {
|
||||
if (remove) {
|
||||
delete meta[key];
|
||||
@ -761,24 +827,24 @@ const internalCertificate = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Request a certificate using the http challenge
|
||||
* @param {Object} certificate the certificate row
|
||||
* @returns {Promise}
|
||||
*/
|
||||
requestLetsEncryptSsl: (certificate) => {
|
||||
logger.info('Requesting Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
||||
|
||||
let cmd = certbot_command + ' certonly --non-interactive ' +
|
||||
'--config "' + le_config + '" ' +
|
||||
const cmd = certbotCommand + ' certonly ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
'--cert-name "npm-' + certificate.id + '" ' +
|
||||
'--agree-tos ' +
|
||||
'--authenticator webroot ' +
|
||||
'--email "' + certificate.meta.letsencrypt_email + '" ' +
|
||||
'--preferred-challenges "dns,http" ' +
|
||||
'--domains "' + certificate.domain_names.join(',') + '" ' +
|
||||
(le_staging ? '--staging' : '');
|
||||
(letsencryptStaging ? '--staging' : '');
|
||||
|
||||
if (debug_mode) {
|
||||
logger.info('Command:', cmd);
|
||||
}
|
||||
logger.info('Command:', cmd);
|
||||
|
||||
return utils.exec(cmd)
|
||||
.then((result) => {
|
||||
@ -788,14 +854,14 @@ const internalCertificate = {
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Object} certificate the certificate row
|
||||
* @param {String} dns_provider the dns provider name (key used in `certbot-dns-plugins.js`)
|
||||
* @param {String | null} credentials the content of this providers credentials file
|
||||
* @param {String} propagation_seconds the cloudflare api token
|
||||
* @param {Object} certificate the certificate row
|
||||
* @param {String} dns_provider the dns provider name (key used in `certbot-dns-plugins.js`)
|
||||
* @param {String | null} credentials the content of this providers credentials file
|
||||
* @param {String} propagation_seconds the cloudflare api token
|
||||
* @returns {Promise}
|
||||
*/
|
||||
requestLetsEncryptSslWithDnsChallenge: (certificate) => {
|
||||
const dns_plugin = dns_plugins[certificate.meta.dns_provider];
|
||||
const dns_plugin = dnsPlugins[certificate.meta.dns_provider];
|
||||
|
||||
if (!dns_plugin) {
|
||||
throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`);
|
||||
@ -803,46 +869,44 @@ const internalCertificate = {
|
||||
|
||||
logger.info(`Requesting Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
|
||||
|
||||
const credentials_loc = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
|
||||
const credentials_cmd = 'mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo \'' + certificate.meta.dns_provider_credentials.replace('\'', '\\\'') + '\' > \'' + credentials_loc + '\' && chmod 600 \'' + credentials_loc + '\'';
|
||||
const prepare_cmd = 'pip install ' + dns_plugin.package_name + '==' + dns_plugin.package_version + ' ' + dns_plugin.dependencies;
|
||||
const credentialsLocation = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
|
||||
const credentialsCmd = 'mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo \'' + certificate.meta.dns_provider_credentials.replace('\'', '\\\'') + '\' > \'' + credentialsLocation + '\' && chmod 600 \'' + credentialsLocation + '\'';
|
||||
const prepareCmd = 'pip install ' + dns_plugin.package_name + (dns_plugin.version_requirement || '') + ' ' + dns_plugin.dependencies;
|
||||
|
||||
// Whether the plugin has a --<name>-credentials argument
|
||||
const has_config_arg = certificate.meta.dns_provider !== 'route53';
|
||||
const hasConfigArg = certificate.meta.dns_provider !== 'route53';
|
||||
|
||||
let main_cmd =
|
||||
certbot_command + ' certonly --non-interactive ' +
|
||||
let mainCmd = certbotCommand + ' certonly ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
'--cert-name "npm-' + certificate.id + '" ' +
|
||||
'--agree-tos ' +
|
||||
'--email "' + certificate.meta.letsencrypt_email + '" ' +
|
||||
'--email "' + certificate.meta.letsencrypt_email + '" ' +
|
||||
'--domains "' + certificate.domain_names.join(',') + '" ' +
|
||||
'--authenticator ' + dns_plugin.full_plugin_name + ' ' +
|
||||
(
|
||||
has_config_arg
|
||||
? '--' + dns_plugin.full_plugin_name + '-credentials "' + credentials_loc + '"'
|
||||
hasConfigArg
|
||||
? '--' + dns_plugin.full_plugin_name + '-credentials "' + credentialsLocation + '"'
|
||||
: ''
|
||||
) +
|
||||
(
|
||||
certificate.meta.propagation_seconds !== undefined
|
||||
? ' --' + dns_plugin.full_plugin_name + '-propagation-seconds ' + certificate.meta.propagation_seconds
|
||||
certificate.meta.propagation_seconds !== undefined
|
||||
? ' --' + dns_plugin.full_plugin_name + '-propagation-seconds ' + certificate.meta.propagation_seconds
|
||||
: ''
|
||||
) +
|
||||
(le_staging ? ' --staging' : '');
|
||||
(letsencryptStaging ? ' --staging' : '');
|
||||
|
||||
// Prepend the path to the credentials file as an environment variable
|
||||
if (certificate.meta.dns_provider === 'route53') {
|
||||
main_cmd = 'AWS_CONFIG_FILE=\'' + credentials_loc + '\' ' + main_cmd;
|
||||
mainCmd = 'AWS_CONFIG_FILE=\'' + credentialsLocation + '\' ' + mainCmd;
|
||||
}
|
||||
|
||||
if (debug_mode) {
|
||||
logger.info('Command:', `${credentials_cmd} && ${prepare_cmd} && ${main_cmd}`);
|
||||
}
|
||||
logger.info('Command:', `${credentialsCmd} && ${prepareCmd} && ${mainCmd}`);
|
||||
|
||||
return utils.exec(credentials_cmd)
|
||||
return utils.exec(credentialsCmd)
|
||||
.then(() => {
|
||||
return utils.exec(prepare_cmd)
|
||||
return utils.exec(prepareCmd)
|
||||
.then(() => {
|
||||
return utils.exec(main_cmd)
|
||||
return utils.exec(mainCmd)
|
||||
.then(async (result) => {
|
||||
logger.info(result);
|
||||
return result;
|
||||
@ -850,8 +914,8 @@ const internalCertificate = {
|
||||
});
|
||||
}).catch(async (err) => {
|
||||
// Don't fail if file does not exist
|
||||
const delete_credentials_cmd = `rm -f '${credentials_loc}' || true`;
|
||||
await utils.exec(delete_credentials_cmd);
|
||||
const delete_credentialsCmd = `rm -f '${credentialsLocation}' || true`;
|
||||
await utils.exec(delete_credentialsCmd);
|
||||
throw err;
|
||||
});
|
||||
},
|
||||
@ -870,7 +934,7 @@ const internalCertificate = {
|
||||
})
|
||||
.then((certificate) => {
|
||||
if (certificate.provider === 'letsencrypt') {
|
||||
let renewMethod = certificate.meta.dns_challenge ? internalCertificate.renewLetsEncryptSslWithDnsChallenge : internalCertificate.renewLetsEncryptSsl;
|
||||
const renewMethod = certificate.meta.dns_challenge ? internalCertificate.renewLetsEncryptSslWithDnsChallenge : internalCertificate.renewLetsEncryptSsl;
|
||||
|
||||
return renewMethod(certificate)
|
||||
.then(() => {
|
||||
@ -908,16 +972,15 @@ const internalCertificate = {
|
||||
renewLetsEncryptSsl: (certificate) => {
|
||||
logger.info('Renewing Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
||||
|
||||
let cmd = certbot_command + ' renew --non-interactive ' +
|
||||
'--config "' + le_config + '" ' +
|
||||
const cmd = certbotCommand + ' renew --force-renewal ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
'--cert-name "npm-' + certificate.id + '" ' +
|
||||
'--preferred-challenges "dns,http" ' +
|
||||
'--no-random-sleep-on-renew ' +
|
||||
'--disable-hook-validation ' +
|
||||
(le_staging ? '--staging' : '');
|
||||
(letsencryptStaging ? '--staging' : '');
|
||||
|
||||
if (debug_mode) {
|
||||
logger.info('Command:', cmd);
|
||||
}
|
||||
logger.info('Command:', cmd);
|
||||
|
||||
return utils.exec(cmd)
|
||||
.then((result) => {
|
||||
@ -931,7 +994,7 @@ const internalCertificate = {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
renewLetsEncryptSslWithDnsChallenge: (certificate) => {
|
||||
const dns_plugin = dns_plugins[certificate.meta.dns_provider];
|
||||
const dns_plugin = dnsPlugins[certificate.meta.dns_provider];
|
||||
|
||||
if (!dns_plugin) {
|
||||
throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`);
|
||||
@ -939,23 +1002,22 @@ const internalCertificate = {
|
||||
|
||||
logger.info(`Renewing Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
|
||||
|
||||
let main_cmd =
|
||||
certbot_command + ' renew --non-interactive ' +
|
||||
let mainCmd = certbotCommand + ' renew ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
'--cert-name "npm-' + certificate.id + '" ' +
|
||||
'--disable-hook-validation' +
|
||||
(le_staging ? ' --staging' : '');
|
||||
'--disable-hook-validation ' +
|
||||
'--no-random-sleep-on-renew ' +
|
||||
(letsencryptStaging ? ' --staging' : '');
|
||||
|
||||
// Prepend the path to the credentials file as an environment variable
|
||||
if (certificate.meta.dns_provider === 'route53') {
|
||||
const credentials_loc = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
|
||||
main_cmd = 'AWS_CONFIG_FILE=\'' + credentials_loc + '\' ' + main_cmd;
|
||||
const credentialsLocation = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
|
||||
mainCmd = 'AWS_CONFIG_FILE=\'' + credentialsLocation + '\' ' + mainCmd;
|
||||
}
|
||||
|
||||
if (debug_mode) {
|
||||
logger.info('Command:', main_cmd);
|
||||
}
|
||||
logger.info('Command:', mainCmd);
|
||||
|
||||
return utils.exec(main_cmd)
|
||||
return utils.exec(mainCmd)
|
||||
.then(async (result) => {
|
||||
logger.info(result);
|
||||
return result;
|
||||
@ -970,28 +1032,25 @@ const internalCertificate = {
|
||||
revokeLetsEncryptSsl: (certificate, throw_errors) => {
|
||||
logger.info('Revoking Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
||||
|
||||
const main_cmd = certbot_command + ' revoke --non-interactive ' +
|
||||
const mainCmd = certbotCommand + ' revoke ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
'--cert-path "/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' +
|
||||
'--delete-after-revoke ' +
|
||||
(le_staging ? '--staging' : '');
|
||||
(letsencryptStaging ? '--staging' : '');
|
||||
|
||||
// Don't fail command if file does not exist
|
||||
const delete_credentials_cmd = `rm -f '/etc/letsencrypt/credentials/credentials-${certificate.id}' || true`;
|
||||
const delete_credentialsCmd = `rm -f '/etc/letsencrypt/credentials/credentials-${certificate.id}' || true`;
|
||||
|
||||
if (debug_mode) {
|
||||
logger.info('Command:', main_cmd + '; ' + delete_credentials_cmd);
|
||||
}
|
||||
logger.info('Command:', mainCmd + '; ' + delete_credentialsCmd);
|
||||
|
||||
return utils.exec(main_cmd)
|
||||
return utils.exec(mainCmd)
|
||||
.then(async (result) => {
|
||||
await utils.exec(delete_credentials_cmd);
|
||||
await utils.exec(delete_credentialsCmd);
|
||||
logger.info(result);
|
||||
return result;
|
||||
})
|
||||
.catch((err) => {
|
||||
if (debug_mode) {
|
||||
logger.error(err.message);
|
||||
}
|
||||
logger.error(err.message);
|
||||
|
||||
if (throw_errors) {
|
||||
throw err;
|
||||
@ -1004,9 +1063,9 @@ const internalCertificate = {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasLetsEncryptSslCerts: (certificate) => {
|
||||
let le_path = '/etc/letsencrypt/live/npm-' + certificate.id;
|
||||
const letsencryptPath = '/etc/letsencrypt/live/npm-' + certificate.id;
|
||||
|
||||
return fs.existsSync(le_path + '/fullchain.pem') && fs.existsSync(le_path + '/privkey.pem');
|
||||
return fs.existsSync(letsencryptPath + '/fullchain.pem') && fs.existsSync(letsencryptPath + '/privkey.pem');
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1067,6 +1126,94 @@ const internalCertificate = {
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
},
|
||||
|
||||
testHttpsChallenge: async (access, domains) => {
|
||||
await access.can('certificates:list');
|
||||
|
||||
if (!isArray(domains)) {
|
||||
throw new error.InternalValidationError('Domains must be an array of strings');
|
||||
}
|
||||
if (domains.length === 0) {
|
||||
throw new error.InternalValidationError('No domains provided');
|
||||
}
|
||||
|
||||
// Create a test challenge file
|
||||
const testChallengeDir = '/data/letsencrypt-acme-challenge/.well-known/acme-challenge';
|
||||
const testChallengeFile = testChallengeDir + '/test-challenge';
|
||||
fs.mkdirSync(testChallengeDir, {recursive: true});
|
||||
fs.writeFileSync(testChallengeFile, 'Success', {encoding: 'utf8'});
|
||||
|
||||
async function performTestForDomain (domain) {
|
||||
logger.info('Testing http challenge for ' + domain);
|
||||
const url = `http://${domain}/.well-known/acme-challenge/test-challenge`;
|
||||
const formBody = `method=G&url=${encodeURI(url)}&bodytype=T&requestbody=&headername=User-Agent&headervalue=None&locationid=1&ch=false&cc=false`;
|
||||
const options = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Content-Length': Buffer.byteLength(formBody)
|
||||
}
|
||||
};
|
||||
|
||||
const result = await new Promise((resolve) => {
|
||||
|
||||
const req = https.request('https://www.site24x7.com/tools/restapi-tester', options, function (res) {
|
||||
let responseBody = '';
|
||||
|
||||
res.on('data', (chunk) => responseBody = responseBody + chunk);
|
||||
res.on('end', function () {
|
||||
const parsedBody = JSON.parse(responseBody + '');
|
||||
if (res.statusCode !== 200) {
|
||||
logger.warn(`Failed to test HTTP challenge for domain ${domain}`, res);
|
||||
resolve(undefined);
|
||||
}
|
||||
resolve(parsedBody);
|
||||
});
|
||||
});
|
||||
|
||||
// Make sure to write the request body.
|
||||
req.write(formBody);
|
||||
req.end();
|
||||
req.on('error', function (e) { logger.warn(`Failed to test HTTP challenge for domain ${domain}`, e);
|
||||
resolve(undefined); });
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
// Some error occurred while trying to get the data
|
||||
return 'failed';
|
||||
} else if (`${result.responsecode}` === '200' && result.htmlresponse === 'Success') {
|
||||
// Server exists and has responded with the correct data
|
||||
return 'ok';
|
||||
} else if (`${result.responsecode}` === '200') {
|
||||
// Server exists but has responded with wrong data
|
||||
logger.info(`HTTP challenge test failed for domain ${domain} because of invalid returned data:`, result.htmlresponse);
|
||||
return 'wrong-data';
|
||||
} else if (`${result.responsecode}` === '404') {
|
||||
// Server exists but responded with a 404
|
||||
logger.info(`HTTP challenge test failed for domain ${domain} because code 404 was returned`);
|
||||
return '404';
|
||||
} else if (`${result.responsecode}` === '0' || (typeof result.reason === 'string' && result.reason.toLowerCase() === 'host unavailable')) {
|
||||
// Server does not exist at domain
|
||||
logger.info(`HTTP challenge test failed for domain ${domain} the host was not found`);
|
||||
return 'no-host';
|
||||
} else {
|
||||
// Other errors
|
||||
logger.info(`HTTP challenge test failed for domain ${domain} because code ${result.responsecode} was returned`);
|
||||
return `other:${result.responsecode}`;
|
||||
}
|
||||
}
|
||||
|
||||
const results = {};
|
||||
|
||||
for (const domain of domains){
|
||||
results[domain] = await performTestForDomain(domain);
|
||||
}
|
||||
|
||||
// Remove the test challenge file
|
||||
fs.unlinkSync(testChallengeFile);
|
||||
|
||||
return results;
|
||||
}
|
||||
};
|
||||
|
||||
|
40
backend/migrations/20210423103500_stream_domain.js
Normal file
40
backend/migrations/20210423103500_stream_domain.js
Normal file
@ -0,0 +1,40 @@
|
||||
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');
|
||||
});
|
||||
};
|
50
backend/migrations/20211108145214_regenerate_default_host.js
Normal file
50
backend/migrations/20211108145214_regenerate_default_host.js
Normal file
@ -0,0 +1,50 @@
|
||||
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);
|
||||
};
|
@ -5,16 +5,15 @@
|
||||
"main": "js/index.js",
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.0",
|
||||
"archiver": "^5.3.0",
|
||||
"batchflow": "^0.4.0",
|
||||
"bcrypt": "^5.0.0",
|
||||
"body-parser": "^1.19.0",
|
||||
"compression": "^1.7.4",
|
||||
"config": "^3.3.1",
|
||||
"diskdb": "^0.1.17",
|
||||
"express": "^4.17.1",
|
||||
"express-fileupload": "^1.1.9",
|
||||
"gravatar": "^1.8.0",
|
||||
"html-entities": "^1.2.1",
|
||||
"json-schema-ref-parser": "^8.0.0",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"knex": "^0.20.13",
|
||||
@ -24,14 +23,11 @@
|
||||
"mysql": "^2.18.1",
|
||||
"node-rsa": "^1.0.8",
|
||||
"nodemon": "^2.0.2",
|
||||
"objection": "^2.1.3",
|
||||
"objection": "^2.2.16",
|
||||
"path": "^0.12.7",
|
||||
"pg": "^7.12.1",
|
||||
"restler": "^3.4.0",
|
||||
"signale": "^1.4.0",
|
||||
"sqlite3": "^4.1.1",
|
||||
"temp-write": "^4.0.0",
|
||||
"unix-timestamp": "^0.2.0"
|
||||
"temp-write": "^4.0.0"
|
||||
},
|
||||
"signale": {
|
||||
"displayDate": true,
|
||||
|
@ -68,6 +68,32 @@ router
|
||||
.catch(next);
|
||||
});
|
||||
|
||||
/**
|
||||
* Test HTTP challenge for domains
|
||||
*
|
||||
* /api/nginx/certificates/test-http
|
||||
*/
|
||||
router
|
||||
.route('/test-http')
|
||||
.options((req, res) => {
|
||||
res.sendStatus(204);
|
||||
})
|
||||
.all(jwtdecode())
|
||||
|
||||
/**
|
||||
* GET /api/nginx/certificates/test-http
|
||||
*
|
||||
* Test HTTP challenge for domains
|
||||
*/
|
||||
.get((req, res, next) => {
|
||||
internalCertificate.testHttpsChallenge(res.locals.access, JSON.parse(req.query.domains))
|
||||
.then((result) => {
|
||||
res.status(200)
|
||||
.send(result);
|
||||
})
|
||||
.catch(next);
|
||||
});
|
||||
|
||||
/**
|
||||
* Specific certificate
|
||||
*
|
||||
@ -209,6 +235,34 @@ router
|
||||
.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
|
||||
*
|
||||
|
@ -153,7 +153,7 @@
|
||||
"example": "john@example.com",
|
||||
"format": "email",
|
||||
"type": "string",
|
||||
"minLength": 8,
|
||||
"minLength": 6,
|
||||
"maxLength": 100
|
||||
},
|
||||
"password": {
|
||||
|
@ -157,6 +157,17 @@
|
||||
"targetSchema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Test HTTP Challenge",
|
||||
"description": "Tests whether the HTTP challenge should work",
|
||||
"href": "/nginx/certificates/{definitions.identity.example}/test-http",
|
||||
"access": "private",
|
||||
"method": "GET",
|
||||
"rel": "info",
|
||||
"http_header": {
|
||||
"$ref": "../examples.json#/definitions/auth_header"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -20,9 +20,20 @@
|
||||
"minimum": 1,
|
||||
"maximum": 65535
|
||||
},
|
||||
"forward_ip": {
|
||||
"type": "string",
|
||||
"format": "ipv4"
|
||||
"forwarding_host": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "../definitions.json#/definitions/domain_name"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"format": "ipv4"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"format": "ipv6"
|
||||
}
|
||||
]
|
||||
},
|
||||
"forwarding_port": {
|
||||
"type": "integer",
|
||||
@ -55,8 +66,8 @@
|
||||
"incoming_port": {
|
||||
"$ref": "#/definitions/incoming_port"
|
||||
},
|
||||
"forward_ip": {
|
||||
"$ref": "#/definitions/forward_ip"
|
||||
"forwarding_host": {
|
||||
"$ref": "#/definitions/forwarding_host"
|
||||
},
|
||||
"forwarding_port": {
|
||||
"$ref": "#/definitions/forwarding_port"
|
||||
@ -107,15 +118,15 @@
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"incoming_port",
|
||||
"forward_ip",
|
||||
"forwarding_host",
|
||||
"forwarding_port"
|
||||
],
|
||||
"properties": {
|
||||
"incoming_port": {
|
||||
"$ref": "#/definitions/incoming_port"
|
||||
},
|
||||
"forward_ip": {
|
||||
"$ref": "#/definitions/forward_ip"
|
||||
"forwarding_host": {
|
||||
"$ref": "#/definitions/forwarding_host"
|
||||
},
|
||||
"forwarding_port": {
|
||||
"$ref": "#/definitions/forwarding_port"
|
||||
@ -154,8 +165,8 @@
|
||||
"incoming_port": {
|
||||
"$ref": "#/definitions/incoming_port"
|
||||
},
|
||||
"forward_ip": {
|
||||
"$ref": "#/definitions/forward_ip"
|
||||
"forwarding_host": {
|
||||
"$ref": "#/definitions/forwarding_host"
|
||||
},
|
||||
"forwarding_port": {
|
||||
"$ref": "#/definitions/forwarding_port"
|
||||
|
@ -175,7 +175,7 @@ const setupCertbotPlugins = () => {
|
||||
certificates.map(function (certificate) {
|
||||
if (certificate.meta && certificate.meta.dns_challenge === true) {
|
||||
const dns_plugin = dns_plugins[certificate.meta.dns_provider];
|
||||
const packages_to_install = `${dns_plugin.package_name}==${dns_plugin.package_version} ${dns_plugin.dependencies}`;
|
||||
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);
|
||||
|
||||
@ -201,9 +201,31 @@ const setupCertbotPlugins = () => {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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 () {
|
||||
return setupJwt()
|
||||
.then(setupDefaultUser)
|
||||
.then(setupDefaultSettings)
|
||||
.then(setupCertbotPlugins);
|
||||
.then(setupCertbotPlugins)
|
||||
.then(setupLogrotation);
|
||||
};
|
||||
|
@ -7,7 +7,7 @@
|
||||
{% if certificate -%}
|
||||
listen 443 ssl{% if http2_support %} http2{% endif %};
|
||||
{% if ipv6 -%}
|
||||
listen [::]:443;
|
||||
listen [::]:443 ssl{% if http2_support %} http2{% endif %};
|
||||
{% else -%}
|
||||
#listen [::]:443;
|
||||
{% endif %}
|
||||
|
@ -7,7 +7,8 @@ server {
|
||||
{% include "_hsts.conf" %}
|
||||
{% include "_forced_ssl.conf" %}
|
||||
|
||||
access_log /data/logs/dead_host-{{ id }}.log standard;
|
||||
access_log /data/logs/dead-host-{{ id }}_access.log standard;
|
||||
error_log /data/logs/dead-host-{{ id }}_error.log warn;
|
||||
|
||||
{{ advanced_config }}
|
||||
|
||||
|
@ -7,14 +7,17 @@
|
||||
server {
|
||||
listen 80 default;
|
||||
{% if ipv6 -%}
|
||||
listen [::]:80;
|
||||
listen [::]:80 default;
|
||||
{% else -%}
|
||||
#listen [::]:80;
|
||||
#listen [::]:80 default;
|
||||
{% endif %}
|
||||
server_name default-host.localhost;
|
||||
access_log /data/logs/default_host.log combined;
|
||||
access_log /data/logs/default-host_access.log combined;
|
||||
error_log /data/logs/default-host_error.log warn;
|
||||
{% include "_exploits.conf" %}
|
||||
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
|
||||
{%- if value == "404" %}
|
||||
location / {
|
||||
return 404;
|
||||
|
@ -8,7 +8,8 @@ server {
|
||||
|
||||
server_name {{ domain_names | join: " " }};
|
||||
|
||||
access_log /data/logs/letsencrypt-requests.log standard;
|
||||
access_log /data/logs/letsencrypt-requests_access.log standard;
|
||||
error_log /data/logs/letsencrypt-requests_error.log warn;
|
||||
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
|
||||
|
@ -19,8 +19,8 @@ proxy_set_header Connection $http_connection;
|
||||
proxy_http_version 1.1;
|
||||
{% endif %}
|
||||
|
||||
|
||||
access_log /data/logs/proxy_host-{{ id }}.log proxy;
|
||||
access_log /data/logs/proxy-host-{{ id }}_access.log proxy;
|
||||
error_log /data/logs/proxy-host-{{ id }}_error.log warn;
|
||||
|
||||
{{ advanced_config }}
|
||||
|
||||
|
@ -9,7 +9,8 @@ server {
|
||||
{% include "_hsts.conf" %}
|
||||
{% include "_forced_ssl.conf" %}
|
||||
|
||||
access_log /data/logs/redirection_host-{{ id }}.log standard;
|
||||
access_log /data/logs/redirection-host-{{ id }}_access.log standard;
|
||||
error_log /data/logs/redirection-host-{{ id }}_error.log warn;
|
||||
|
||||
{{ advanced_config }}
|
||||
|
||||
|
@ -12,7 +12,7 @@ server {
|
||||
#listen [::]:{{ incoming_port }};
|
||||
{% endif %}
|
||||
|
||||
proxy_pass {{ forward_ip }}:{{ forwarding_port }};
|
||||
proxy_pass {{ forwarding_host }}:{{ forwarding_port }};
|
||||
|
||||
# Custom
|
||||
include /data/nginx/custom/server_stream[.]conf;
|
||||
@ -27,7 +27,7 @@ server {
|
||||
{% else -%}
|
||||
#listen [::]:{{ incoming_port }} udp;
|
||||
{% endif %}
|
||||
proxy_pass {{ forward_ip }}:{{ forwarding_port }};
|
||||
proxy_pass {{ forwarding_host }}:{{ forwarding_port }};
|
||||
|
||||
# Custom
|
||||
include /data/nginx/custom/server_stream[.]conf;
|
||||
|
@ -77,10 +77,10 @@ acorn@^7.1.1:
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c"
|
||||
integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==
|
||||
|
||||
ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0:
|
||||
version "6.12.3"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706"
|
||||
integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==
|
||||
ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.6:
|
||||
version "6.12.6"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
|
||||
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.1"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
@ -136,11 +136,6 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
||||
"@types/color-name" "^1.1.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:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142"
|
||||
@ -154,6 +149,35 @@ aproba@^1.0.3:
|
||||
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
|
||||
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:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21"
|
||||
@ -221,6 +245,11 @@ astral-regex@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
|
||||
integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
|
||||
|
||||
async@^3.2.0:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-3.2.1.tgz#d3274ec66d107a47476a4c49136aacdb00665fc8"
|
||||
integrity sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==
|
||||
|
||||
atob@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||
@ -231,6 +260,11 @@ balanced-match@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
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:
|
||||
version "0.11.2"
|
||||
resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
|
||||
@ -267,6 +301,15 @@ binary-extensions@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9"
|
||||
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:
|
||||
version "2.17.0"
|
||||
resolved "https://registry.yarnpkg.com/blueimp-md5/-/blueimp-md5-2.17.0.tgz#f4fcac088b115f7b4045f19f5da59e9d01b1bb96"
|
||||
@ -333,15 +376,23 @@ braces@~3.0.2:
|
||||
dependencies:
|
||||
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:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
|
||||
integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
|
||||
|
||||
buffer-writer@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04"
|
||||
integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==
|
||||
buffer@^5.5.0:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
|
||||
integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
|
||||
dependencies:
|
||||
base64-js "^1.3.1"
|
||||
ieee754 "^1.1.13"
|
||||
|
||||
busboy@^0.3.1:
|
||||
version "0.3.1"
|
||||
@ -403,15 +454,6 @@ camelcase@^5.0.0, camelcase@^5.3.1:
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
|
||||
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:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||
@ -457,7 +499,7 @@ chokidar@^3.2.2:
|
||||
optionalDependencies:
|
||||
fsevents "~2.1.2"
|
||||
|
||||
chownr@^1.1.1:
|
||||
chownr@^1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
|
||||
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
|
||||
@ -562,6 +604,16 @@ component-emitter@^1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
|
||||
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:
|
||||
version "2.0.18"
|
||||
resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"
|
||||
@ -643,6 +695,22 @@ core-util-is@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
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:
|
||||
version "6.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
||||
@ -771,15 +839,6 @@ dicer@0.3.0:
|
||||
dependencies:
|
||||
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:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
|
||||
@ -831,7 +890,7 @@ encodeurl@~1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
|
||||
|
||||
end-of-stream@^1.1.0:
|
||||
end-of-stream@^1.1.0, end-of-stream@^1.4.1:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
||||
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
|
||||
@ -981,6 +1040,11 @@ etag@~1.8.1:
|
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
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:
|
||||
version "2.1.4"
|
||||
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622"
|
||||
@ -1237,7 +1301,12 @@ fresh@0.5.2:
|
||||
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
||||
integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
|
||||
|
||||
fs-minipass@^1.2.5:
|
||||
fs-constants@^1.0.0:
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
|
||||
integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==
|
||||
@ -1321,6 +1390,18 @@ glob@^7.1.3:
|
||||
once "^1.3.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:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.0.1.tgz#acdf3bb6685bcd55cb35e8a052266569e9469201"
|
||||
@ -1377,6 +1458,11 @@ graceful-fs@^4.1.15, graceful-fs@^4.1.2:
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
||||
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:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/gravatar/-/gravatar-1.8.1.tgz#743bbdf3185c3433172e00e0e6ff5f6b30c58997"
|
||||
@ -1387,11 +1473,6 @@ gravatar@^1.8.0:
|
||||
querystring "0.2.0"
|
||||
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:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
@ -1450,11 +1531,6 @@ homedir-polyfill@^1.0.1:
|
||||
dependencies:
|
||||
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:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
|
||||
@ -1482,11 +1558,6 @@ http-errors@~1.7.2:
|
||||
statuses ">= 1.5.0 < 2"
|
||||
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:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
@ -1494,6 +1565,11 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
|
||||
dependencies:
|
||||
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:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
|
||||
@ -1537,7 +1613,7 @@ inflight@^1.0.4:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2, 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, inherits@~2.0.3, inherits@~2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
@ -1937,6 +2013,13 @@ latest-version@^5.0.0:
|
||||
dependencies:
|
||||
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:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
|
||||
@ -1989,6 +2072,21 @@ locate-path@^5.0.0:
|
||||
dependencies:
|
||||
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:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
|
||||
@ -2024,6 +2122,11 @@ lodash.once@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
||||
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
|
||||
|
||||
lodash.union@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88"
|
||||
integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=
|
||||
|
||||
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"
|
||||
@ -2075,11 +2178,6 @@ merge-descriptors@1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
|
||||
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:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
||||
@ -2143,7 +2241,7 @@ minimist@^1.2.0, minimist@^1.2.5:
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
|
||||
minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0:
|
||||
minipass@^2.6.0, minipass@^2.9.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6"
|
||||
integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==
|
||||
@ -2151,7 +2249,7 @@ minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0:
|
||||
safe-buffer "^5.1.2"
|
||||
yallist "^3.0.0"
|
||||
|
||||
minizlib@^1.2.1:
|
||||
minizlib@^1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d"
|
||||
integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==
|
||||
@ -2166,7 +2264,7 @@ mixin-deep@^1.2.0:
|
||||
for-in "^1.0.2"
|
||||
is-extendable "^1.0.1"
|
||||
|
||||
mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3:
|
||||
mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5:
|
||||
version "0.5.5"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
||||
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
|
||||
@ -2298,11 +2396,6 @@ node-rsa@^1.0.8:
|
||||
dependencies:
|
||||
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:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.4.tgz#55b09319eb488d6394aa9818148c0c2d1c04c416"
|
||||
@ -2340,9 +2433,9 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||
|
||||
normalize-url@^4.1.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
|
||||
integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==
|
||||
version "4.5.1"
|
||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a"
|
||||
integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==
|
||||
|
||||
npm-bundled@^1.0.1:
|
||||
version "1.1.1"
|
||||
@ -2426,12 +2519,12 @@ object.pick@^1.2.0, object.pick@^1.3.0:
|
||||
dependencies:
|
||||
isobject "^3.0.1"
|
||||
|
||||
objection@^2.1.3:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/objection/-/objection-2.2.2.tgz#1a3c9010270e3677940d2bc91aeaeb3c0f103800"
|
||||
integrity sha512-+1Ap7u9NQRochzDW5/BggUlKi94JfZGTJwQJuNXo8DwmAb8czEirvxcWBcX91/MmQq0BQUJjM4RPSiZhnkkWQw==
|
||||
objection@^2.2.16:
|
||||
version "2.2.16"
|
||||
resolved "https://registry.yarnpkg.com/objection/-/objection-2.2.16.tgz#552ec6d625a7f80d6e204fc63732cbd3fc56f31c"
|
||||
integrity sha512-sq8erZdxW5ruPUK6tVvwDxyO16U49XAn/BmOm2zaNhNA2phOPCe2/7+R70nDEF1SFrgJOrwDu/PtoxybuJxnjQ==
|
||||
dependencies:
|
||||
ajv "^6.12.0"
|
||||
ajv "^6.12.6"
|
||||
db-errors "^0.2.3"
|
||||
|
||||
on-finished@~2.3.0:
|
||||
@ -2543,11 +2636,6 @@ package-json@^6.3.0:
|
||||
registry-url "^5.0.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:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
|
||||
@ -2608,9 +2696,9 @@ path-key@^2.0.1:
|
||||
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
|
||||
|
||||
path-parse@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
|
||||
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||
|
||||
path-root-regex@^0.1.0:
|
||||
version "0.1.2"
|
||||
@ -2637,63 +2725,11 @@ path@^0.12.7:
|
||||
process "^0.11.1"
|
||||
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:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.1.0.tgz#e07258f280476540b24818ebb5dca29e101ca502"
|
||||
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:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
|
||||
@ -2717,28 +2753,6 @@ posix-character-classes@^0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
|
||||
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:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
||||
@ -2754,6 +2768,11 @@ prettier@^2.0.4:
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4"
|
||||
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:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
||||
@ -2802,11 +2821,6 @@ pupa@^2.0.1:
|
||||
dependencies:
|
||||
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:
|
||||
version "6.7.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
|
||||
@ -2842,7 +2856,7 @@ rc@^1.2.7, rc@^1.2.8:
|
||||
minimist "^1.2.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
|
||||
readable-stream@2.3.7, readable-stream@^2.0.6:
|
||||
readable-stream@2.3.7, readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.0.6:
|
||||
version "2.3.7"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
||||
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
|
||||
@ -2855,6 +2869,22 @@ readable-stream@2.3.7, readable-stream@^2.0.6:
|
||||
string_decoder "~1.1.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:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada"
|
||||
@ -2948,16 +2978,6 @@ responselike@^1.0.2:
|
||||
dependencies:
|
||||
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:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e"
|
||||
@ -3002,7 +3022,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"
|
||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||
|
||||
safe-buffer@^5.0.1, safe-buffer@^5.1.2:
|
||||
safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@^5.2.1, safe-buffer@~5.2.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
@ -3019,11 +3039,6 @@ safe-regex@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
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:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||
@ -3036,11 +3051,6 @@ semver-diff@^3.1.1:
|
||||
dependencies:
|
||||
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:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
@ -3193,13 +3203,6 @@ split-string@^3.0.1, split-string@^3.0.2:
|
||||
dependencies:
|
||||
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:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
@ -3271,6 +3274,13 @@ string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0:
|
||||
is-fullwidth-code-point "^3.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:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
|
||||
@ -3306,11 +3316,6 @@ strip-ansi@^6.0.0:
|
||||
dependencies:
|
||||
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:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||
@ -3350,18 +3355,29 @@ table@^5.2.3:
|
||||
slice-ansi "^2.1.0"
|
||||
string-width "^3.0.0"
|
||||
|
||||
tar@^4, tar@^4.4.2:
|
||||
version "4.4.13"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
|
||||
integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
|
||||
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:
|
||||
chownr "^1.1.1"
|
||||
fs-minipass "^1.2.5"
|
||||
minipass "^2.8.6"
|
||||
minizlib "^1.2.1"
|
||||
mkdirp "^0.5.0"
|
||||
safe-buffer "^5.1.2"
|
||||
yallist "^3.0.3"
|
||||
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:
|
||||
version "4.4.19"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3"
|
||||
integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==
|
||||
dependencies:
|
||||
chownr "^1.1.4"
|
||||
fs-minipass "^1.2.7"
|
||||
minipass "^2.9.0"
|
||||
minizlib "^1.3.3"
|
||||
mkdirp "^0.5.5"
|
||||
safe-buffer "^5.2.1"
|
||||
yallist "^3.1.1"
|
||||
|
||||
tarn@^2.0.0:
|
||||
version "2.0.0"
|
||||
@ -3394,7 +3410,7 @@ text-table@^0.2.0:
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
|
||||
|
||||
through@2, through@^2.3.6:
|
||||
through@^2.3.6:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
||||
@ -3526,11 +3542,6 @@ unique-string@^2.0.0:
|
||||
dependencies:
|
||||
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:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
||||
@ -3587,7 +3598,7 @@ use@^3.1.0:
|
||||
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||
@ -3698,39 +3709,16 @@ xdg-basedir@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
|
||||
integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==
|
||||
|
||||
xml2js@0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.0.tgz#124fc4114b4129c810800ecb2ac86cf25462cb9a"
|
||||
integrity sha1-Ek/EEUtBKcgQgA7LKshs8lRiy5o=
|
||||
dependencies:
|
||||
sax "0.5.x"
|
||||
xmlbuilder ">=0.4.2"
|
||||
|
||||
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.1"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4"
|
||||
integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==
|
||||
|
||||
yallist@^3.0.0, yallist@^3.0.3:
|
||||
yallist@^3.0.0, yallist@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
|
||||
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:
|
||||
version "18.1.3"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
|
||||
@ -3755,3 +3743,12 @@ yargs@^15.4.1:
|
||||
which-module "^2.0.0"
|
||||
y18n "^4.0.0"
|
||||
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"
|
||||
|
14
docker/.dive-ci
Normal file
14
docker/.dive-ci
Normal file
@ -0,0 +1,14 @@
|
||||
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
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
# This file assumes that the frontend has been built using ./scripts/frontend-build
|
||||
|
||||
FROM jc21/nginx-full:node
|
||||
FROM nginxproxymanager/nginx-full:node
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
ARG BUILD_VERSION
|
||||
@ -20,7 +20,7 @@ ENV SUPPRESS_NO_CONFIG_WARNING=1 \
|
||||
|
||||
RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends jq \
|
||||
&& apt-get install -y --no-install-recommends jq logrotate \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@ -43,9 +43,11 @@ COPY docker/rootfs /
|
||||
# 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
|
||||
|
||||
# Change permission of logrotate config file
|
||||
RUN chmod 644 /etc/logrotate.d/nginx-proxy-manager
|
||||
|
||||
VOLUME [ "/data", "/etc/letsencrypt" ]
|
||||
ENTRYPOINT [ "/init" ]
|
||||
HEALTHCHECK --interval=5s --timeout=3s CMD /bin/check-health
|
||||
|
||||
LABEL org.label-schema.schema-version="1.0" \
|
||||
org.label-schema.license="MIT" \
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM jc21/nginx-full:node
|
||||
FROM nginxproxymanager/nginx-full:node
|
||||
LABEL maintainer="Jamie Curnow <jc@jc21.com>"
|
||||
|
||||
ENV S6_LOGGING=0 \
|
||||
@ -7,7 +7,7 @@ ENV S6_LOGGING=0 \
|
||||
|
||||
RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y certbot jq python3-pip \
|
||||
&& apt-get install -y certbot jq python3-pip logrotate \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@ -18,6 +18,7 @@ RUN cd /usr \
|
||||
|
||||
COPY rootfs /
|
||||
RUN rm -f /etc/nginx/conf.d/production.conf
|
||||
RUN chmod 644 /etc/logrotate.d/nginx-proxy-manager
|
||||
|
||||
# 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" \
|
||||
@ -25,4 +26,4 @@ RUN curl -L -o /tmp/s6-overlay-amd64.tar.gz "https://github.com/just-containers/
|
||||
|
||||
EXPOSE 80 81 443
|
||||
ENTRYPOINT [ "/init" ]
|
||||
HEALTHCHECK --interval=5s --timeout=3s CMD /bin/check-health
|
||||
|
||||
|
@ -20,6 +20,10 @@ services:
|
||||
- 443
|
||||
depends_on:
|
||||
- db
|
||||
healthcheck:
|
||||
test: ["CMD", "/bin/check-health"]
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
|
||||
fullstack-sqlite:
|
||||
image: ${IMAGE}:ci-${BUILD_NUMBER}
|
||||
@ -33,6 +37,10 @@ services:
|
||||
- 81
|
||||
- 80
|
||||
- 443
|
||||
healthcheck:
|
||||
test: ["CMD", "/bin/check-health"]
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
|
||||
db:
|
||||
image: jc21/mariadb-aria
|
||||
|
@ -1,9 +1,9 @@
|
||||
# WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production.
|
||||
version: "3"
|
||||
version: "3.5"
|
||||
services:
|
||||
|
||||
npm:
|
||||
image: nginxproxymanager:dev
|
||||
container_name: npm_core
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./dev/Dockerfile
|
||||
@ -36,6 +36,9 @@ services:
|
||||
|
||||
db:
|
||||
image: jc21/mariadb-aria
|
||||
container_name: npm_db
|
||||
ports:
|
||||
- 33306:3306
|
||||
networks:
|
||||
- nginx_proxy_manager
|
||||
environment:
|
||||
@ -46,22 +49,14 @@ services:
|
||||
volumes:
|
||||
- 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:
|
||||
npm_data:
|
||||
name: npm_core_data
|
||||
le_data:
|
||||
name: npm_le_data
|
||||
db_data:
|
||||
name: npm_db_data
|
||||
|
||||
networks:
|
||||
nginx_proxy_manager:
|
||||
name: npm_network
|
||||
|
7
docker/rootfs/etc/cont-init.d/01_perms.sh
Executable file
7
docker/rootfs/etc/cont-init.d/01_perms.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/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
|
||||
|
@ -1,4 +1,6 @@
|
||||
text = True
|
||||
non-interactive = True
|
||||
authenticator = webroot
|
||||
webroot-path = /data/letsencrypt-acme-challenge
|
||||
key-type = ecdsa
|
||||
elliptic-curve = secp384r1
|
||||
preferred-chain = ISRG Root X1
|
||||
|
25
docker/rootfs/etc/logrotate.d/nginx-proxy-manager
Normal file
25
docker/rootfs/etc/logrotate.d/nginx-proxy-manager
Normal file
@ -0,0 +1,25 @@
|
||||
/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
|
||||
}
|
@ -8,10 +8,11 @@ server {
|
||||
set $port "80";
|
||||
|
||||
server_name localhost-nginx-proxy-manager;
|
||||
access_log /data/logs/default.log standard;
|
||||
error_log /dev/null crit;
|
||||
access_log /data/logs/fallback_access.log standard;
|
||||
error_log /data/logs/fallback_error.log warn;
|
||||
include conf.d/include/assets.conf;
|
||||
include conf.d/include/block-exploits.conf;
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
|
||||
location / {
|
||||
index index.html;
|
||||
@ -29,7 +30,7 @@ server {
|
||||
set $port "443";
|
||||
|
||||
server_name localhost;
|
||||
access_log /data/logs/default.log standard;
|
||||
access_log /data/logs/fallback-access.log standard;
|
||||
error_log /dev/null crit;
|
||||
ssl_certificate /data/nginx/dummycert.pem;
|
||||
ssl_certificate_key /data/nginx/dummykey.pem;
|
||||
|
@ -5,6 +5,7 @@ location ^~ /.well-known/acme-challenge/ {
|
||||
# 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.
|
||||
auth_basic off;
|
||||
auth_request off;
|
||||
allow all;
|
||||
|
||||
# Set correct content type. According to this:
|
||||
|
@ -4,5 +4,5 @@ proxy_set_header X-Forwarded-Scheme $scheme;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_pass $forward_scheme://$server:$port;
|
||||
proxy_pass $forward_scheme://$server:$port$request_uri;
|
||||
|
||||
|
@ -9,7 +9,7 @@ worker_processes auto;
|
||||
# Enables the use of JIT for regular expressions to speed-up their processing.
|
||||
pcre_jit on;
|
||||
|
||||
error_log /data/logs/error.log warn;
|
||||
error_log /data/logs/fallback_error.log warn;
|
||||
|
||||
# Includes files with directives to load dynamic modules.
|
||||
include /etc/nginx/modules/*.conf;
|
||||
@ -46,8 +46,7 @@ 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 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/default.log proxy;
|
||||
access_log /data/logs/fallback_access.log proxy;
|
||||
|
||||
# Dynamically generated resolvers file
|
||||
include /etc/nginx/conf.d/include/resolvers.conf;
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
if [ "$DEVELOPMENT" == "true" ]; then
|
||||
cd /app/frontend || exit 1
|
||||
# If yarn install fails: add --verbose --network-concurrency 1
|
||||
yarn install
|
||||
yarn watch
|
||||
else
|
||||
|
@ -6,6 +6,7 @@ cd /app || echo
|
||||
|
||||
if [ "$DEVELOPMENT" == "true" ]; then
|
||||
cd /app || exit 1
|
||||
# If yarn install fails: add --verbose --network-concurrency 1
|
||||
yarn install
|
||||
node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js
|
||||
else
|
||||
|
@ -36,7 +36,7 @@ then
|
||||
-days 3650 \
|
||||
-nodes \
|
||||
-x509 \
|
||||
-subj '/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost' \
|
||||
-subj '/O=localhost/OU=localhost/CN=localhost' \
|
||||
-keyout /data/nginx/dummykey.pem \
|
||||
-out /data/nginx/dummycert.pem
|
||||
echo "Complete"
|
||||
|
@ -1,10 +1,10 @@
|
||||
# Advanced Configuration
|
||||
|
||||
## Best Practice: Use a docker network
|
||||
## 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.
|
||||
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":
|
||||
|
||||
@ -13,7 +13,7 @@ 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:
|
||||
services running on this Docker host:
|
||||
|
||||
```yml
|
||||
networks:
|
||||
@ -44,10 +44,22 @@ networks:
|
||||
|
||||
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
|
||||
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.
|
||||
@ -116,7 +128,7 @@ services:
|
||||
|
||||
## 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
|
||||
|
||||
|
@ -443,7 +443,7 @@
|
||||
"normalize-url": "^5.1.0",
|
||||
"npm-run-path": "^4.0.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"nth-check": "^1.0.2",
|
||||
"nth-check": "^2.0.1",
|
||||
"num2fraction": "^1.2.2",
|
||||
"number-is-nan": "^2.0.0",
|
||||
"oauth-sign": "^0.9.0",
|
||||
@ -612,7 +612,7 @@
|
||||
"serve-index": "^1.9.1",
|
||||
"serve-static": "^1.14.1",
|
||||
"set-blocking": "^2.0.0",
|
||||
"set-value": "^3.0.2",
|
||||
"set-value": "^4.0.1",
|
||||
"setimmediate": "^1.0.5",
|
||||
"setprototypeof": "^1.2.0",
|
||||
"sha.js": "^2.4.11",
|
||||
|
@ -1,6 +1,44 @@
|
||||
# Full Setup Instructions
|
||||
|
||||
## MySQL Database
|
||||
## Running the App
|
||||
|
||||
Create a `docker-compose.yml` file:
|
||||
|
||||
```yml
|
||||
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
|
||||
# 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
|
||||
# DISABLE_IPV6: 'true'
|
||||
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./letsencrypt:/etc/letsencrypt
|
||||
```
|
||||
|
||||
Then:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## Using MySQL / MariaDB Database
|
||||
|
||||
If you opt for the MySQL configuration you will have to provide the database server yourself. You can also use MariaDB. Here are the minimum supported versions:
|
||||
|
||||
@ -10,15 +48,7 @@ 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
|
||||
are going to use.
|
||||
|
||||
::: warning
|
||||
|
||||
When using a `mariadb` database, the NPM configuration file should still use the `mysql` engine!
|
||||
|
||||
:::
|
||||
|
||||
## Running the App
|
||||
|
||||
Via `docker-compose`:
|
||||
Here is an example of what your `docker-compose.yml` will look like when using a MariaDB container:
|
||||
|
||||
```yml
|
||||
version: "3"
|
||||
@ -27,24 +57,18 @@ services:
|
||||
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'
|
||||
# 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
|
||||
environment:
|
||||
# These are the settings to access your db
|
||||
DB_MYSQL_HOST: "db"
|
||||
DB_MYSQL_PORT: 3306
|
||||
DB_MYSQL_USER: "npm"
|
||||
DB_MYSQL_PASSWORD: "npm"
|
||||
DB_MYSQL_NAME: "npm"
|
||||
# If you would rather use Sqlite uncomment this
|
||||
# and remove all DB_MYSQL_* lines above
|
||||
# DB_SQLITE_FILE: "/data/database.sqlite"
|
||||
# Uncomment this if IPv6 is not enabled on your host
|
||||
# DISABLE_IPV6: 'true'
|
||||
volumes:
|
||||
@ -52,6 +76,7 @@ services:
|
||||
- ./letsencrypt:/etc/letsencrypt
|
||||
depends_on:
|
||||
- db
|
||||
|
||||
db:
|
||||
image: 'jc21/mariadb-aria:latest'
|
||||
restart: unless-stopped
|
||||
@ -64,13 +89,11 @@ services:
|
||||
- ./data/mysql:/var/lib/mysql
|
||||
```
|
||||
|
||||
_Please note, that `DB_MYSQL_*` environment variables will take precedent over `DB_SQLITE_*` variables. So if you keep the MySQL variables, you will not be able to use Sqlite._
|
||||
::: 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
|
||||
```
|
||||
:::
|
||||
|
||||
## Running on Raspberry PI / ARM devices
|
||||
|
||||
@ -89,57 +112,7 @@ for a list of supported architectures and if you want one that doesn't exist,
|
||||
Also, if you don't know how to already, follow [this guide to install docker and docker-compose](https://manre-universe.net/how-to-run-docker-and-docker-compose-on-raspbian/)
|
||||
on Raspbian.
|
||||
|
||||
Via `docker-compose`:
|
||||
|
||||
```yml
|
||||
version: "3"
|
||||
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: "changeuser"
|
||||
DB_MYSQL_PASSWORD: "changepass"
|
||||
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/nginx-proxy-manager:/data
|
||||
- ./letsencrypt:/etc/letsencrypt
|
||||
depends_on:
|
||||
- db
|
||||
db:
|
||||
image: yobasystems/alpine-mariadb:latest
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: "changeme"
|
||||
MYSQL_DATABASE: "npm"
|
||||
MYSQL_USER: "changeuser"
|
||||
MYSQL_PASSWORD: "changepass"
|
||||
volumes:
|
||||
- ./data/mariadb:/var/lib/mysql
|
||||
```
|
||||
|
||||
_Please note, that `DB_MYSQL_*` environment variables will take precedent over `DB_SQLITE_*` var>
|
||||
|
||||
Then:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
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
|
||||
|
||||
|
@ -1624,9 +1624,9 @@ ansi-regex@^4.1.0:
|
||||
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
|
||||
|
||||
ansi-regex@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
|
||||
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||
|
||||
ansi-styles@^2.2.1:
|
||||
version "2.2.1"
|
||||
@ -2560,7 +2560,7 @@ cli-boxes@^2.2.0:
|
||||
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d"
|
||||
integrity sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==
|
||||
|
||||
clipboard@^2.0.0, clipboard@^2.0.6:
|
||||
clipboard@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.6.tgz#52921296eec0fdf77ead1749421b21c968647376"
|
||||
integrity sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==
|
||||
@ -2650,9 +2650,9 @@ color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4:
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
color-string@^1.5.2, color-string@^1.5.3:
|
||||
version "1.5.3"
|
||||
resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc"
|
||||
integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==
|
||||
version "1.5.5"
|
||||
resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.5.tgz#65474a8f0e7439625f3d27a6a19d89fc45223014"
|
||||
integrity sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==
|
||||
dependencies:
|
||||
color-name "^1.0.0"
|
||||
simple-swizzle "^0.2.2"
|
||||
@ -6405,10 +6405,10 @@ minipass@^3.0.0, minipass@^3.1.1:
|
||||
dependencies:
|
||||
yallist "^4.0.0"
|
||||
|
||||
minizlib@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.0.tgz#fd52c645301ef09a63a2c209697c294c6ce02cf3"
|
||||
integrity sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==
|
||||
minizlib@^2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"
|
||||
integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==
|
||||
dependencies:
|
||||
minipass "^3.0.0"
|
||||
yallist "^4.0.0"
|
||||
@ -6726,6 +6726,13 @@ nth-check@^1.0.2, nth-check@~1.0.1:
|
||||
dependencies:
|
||||
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:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
|
||||
@ -7173,9 +7180,9 @@ path-key@^3.0.0, path-key@^3.1.0, path-key@^3.1.1:
|
||||
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
||||
|
||||
path-parse@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
|
||||
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||
|
||||
path-to-regexp@0.1.7:
|
||||
version "0.1.7"
|
||||
@ -7699,11 +7706,9 @@ pretty-time@^1.1.0:
|
||||
integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==
|
||||
|
||||
prismjs@^1.13.0, prismjs@^1.20.0:
|
||||
version "1.23.0"
|
||||
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.23.0.tgz#d3b3967f7d72440690497652a9d40ff046067f33"
|
||||
integrity sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==
|
||||
optionalDependencies:
|
||||
clipboard "^2.0.0"
|
||||
version "1.25.0"
|
||||
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.25.0.tgz#6f822df1bdad965734b310b315a23315cf999756"
|
||||
integrity sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg==
|
||||
|
||||
private@^0.1.8:
|
||||
version "0.1.8"
|
||||
@ -8438,13 +8443,20 @@ set-value@^2.0.0, set-value@^2.0.1:
|
||||
is-plain-object "^2.0.3"
|
||||
split-string "^3.0.1"
|
||||
|
||||
set-value@^3.0.0, set-value@^3.0.2:
|
||||
set-value@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/set-value/-/set-value-3.0.2.tgz#74e8ecd023c33d0f77199d415409a40f21e61b90"
|
||||
integrity sha512-npjkVoz+ank0zjlV9F47Fdbjfj/PfXyVhZvGALWsyIYU/qrMzpi6avjKW3/7KeSU2Df3I46BrN1xOI1+6vW0hA==
|
||||
dependencies:
|
||||
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:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
|
||||
@ -9156,14 +9168,14 @@ tapable@^1.0.0, tapable@^1.1.3:
|
||||
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
|
||||
|
||||
tar@^6.0.2:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.2.tgz#5df17813468a6264ff14f766886c622b84ae2f39"
|
||||
integrity sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==
|
||||
version "6.1.11"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621"
|
||||
integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==
|
||||
dependencies:
|
||||
chownr "^2.0.0"
|
||||
fs-minipass "^2.0.0"
|
||||
minipass "^3.0.0"
|
||||
minizlib "^2.1.0"
|
||||
minizlib "^2.1.1"
|
||||
mkdirp "^1.0.3"
|
||||
yallist "^4.0.0"
|
||||
|
||||
@ -9652,9 +9664,9 @@ url-parse-lax@^3.0.0:
|
||||
prepend-http "^2.0.0"
|
||||
|
||||
url-parse@^1.4.3, url-parse@^1.4.7:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.0.tgz#90aba6c902aeb2d80eac17b91131c27665d5d828"
|
||||
integrity sha512-9iT6N4s93SMfzunOyDPe4vo4nLcSu1yq0IQK1gURmjm8tQNlM6loiuCRrKG1hHGXfB2EWd6H4cGi7tGdaygMFw==
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.2.tgz#a4eff6fd5ff9fe6ab98ac1f79641819d13247cda"
|
||||
integrity sha512-6bTUPERy1muxxYClbzoRo5qtQuyoGEbzbQvi0SW4/8U8UyVkAQhWFBlnigqJkRm4su4x1zDQfNbEzWkt+vchcg==
|
||||
dependencies:
|
||||
querystringify "^2.1.1"
|
||||
requires-port "^1.0.0"
|
||||
|
@ -152,6 +152,51 @@ 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 = {
|
||||
status: function () {
|
||||
return fetch('get', '');
|
||||
@ -638,6 +683,24 @@ module.exports = {
|
||||
*/
|
||||
renew: function (id, timeout = 180000) {
|
||||
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")
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -366,6 +366,19 @@ 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
|
||||
*/
|
||||
|
@ -18,6 +18,14 @@
|
||||
<input type="text" name="domain_names" class="form-control" id="input-domains" value="<%- domain_names.join(',') %>" required>
|
||||
<div class="text-blue"><i class="fe fe-alert-triangle"></i> <%- i18n('ssl', 'hosts-warning') %></div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 test-domains-container">
|
||||
<button type="button" class="btn btn-secondary test-domains col-sm-12"><%- i18n('certificates', 'test-reachability') %></button>
|
||||
<div class="text-secondary small">
|
||||
<i class="fe fe-info"></i>
|
||||
<%- i18n('certificates', 'reachability-info') %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12">
|
||||
<div class="form-group">
|
||||
|
@ -29,6 +29,8 @@ module.exports = Mn.View.extend({
|
||||
non_loader_content: '.non-loader-content',
|
||||
le_error_info: '#le-error-info',
|
||||
domain_names: 'input[name="domain_names"]',
|
||||
test_domains_container: '.test-domains-container',
|
||||
test_domains_button: '.test-domains',
|
||||
buttons: '.modal-footer button',
|
||||
cancel: 'button.cancel',
|
||||
save: 'button.save',
|
||||
@ -56,10 +58,12 @@ module.exports = Mn.View.extend({
|
||||
this.ui.dns_provider_credentials.prop('required', 'required');
|
||||
}
|
||||
this.ui.dns_challenge_content.show();
|
||||
this.ui.test_domains_container.hide();
|
||||
} else {
|
||||
this.ui.dns_provider.prop('required', false);
|
||||
this.ui.dns_provider_credentials.prop('required', false);
|
||||
this.ui.dns_challenge_content.hide();
|
||||
this.ui.dns_challenge_content.hide();
|
||||
this.ui.test_domains_container.show();
|
||||
}
|
||||
},
|
||||
|
||||
@ -205,6 +209,23 @@ module.exports = Mn.View.extend({
|
||||
this.ui.non_loader_content.show();
|
||||
});
|
||||
},
|
||||
'click @ui.test_domains_button': function (e) {
|
||||
e.preventDefault();
|
||||
const domainNames = this.ui.domain_names[0].value.split(',');
|
||||
if (domainNames && domainNames.length > 0) {
|
||||
this.model.set('domain_names', domainNames);
|
||||
this.model.set('back_to_add', true);
|
||||
App.Controller.showNginxCertificateTestReachability(this.model);
|
||||
}
|
||||
},
|
||||
'change @ui.domain_names': function(e){
|
||||
const domainNames = e.target.value.split(',');
|
||||
if (domainNames && domainNames.length > 0) {
|
||||
this.ui.test_domains_button.prop('disabled', false);
|
||||
} else {
|
||||
this.ui.test_domains_button.prop('disabled', true);
|
||||
}
|
||||
},
|
||||
'change @ui.other_certificate_key': function(e){
|
||||
this.setFileName("other_certificate_key_label", e)
|
||||
},
|
||||
@ -251,12 +272,18 @@ module.exports = Mn.View.extend({
|
||||
text: input
|
||||
};
|
||||
},
|
||||
createFilter: /^(?:[^.]+\.?)+[^.]$/
|
||||
createFilter: /^(?:\*\.)?(?:[^.*]+\.?)+[^.]$/
|
||||
});
|
||||
this.ui.dns_challenge_content.hide();
|
||||
this.ui.credentials_file_content.hide();
|
||||
this.ui.loader_content.hide();
|
||||
this.ui.le_error_info.hide();
|
||||
if (this.ui.domain_names[0]) {
|
||||
const domainNames = this.ui.domain_names[0].value.split(',');
|
||||
if (!domainNames || domainNames.length === 0 || (domainNames.length === 1 && domainNames[0] === "")) {
|
||||
this.ui.test_domains_button.prop('disabled', true);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
|
@ -41,6 +41,10 @@
|
||||
<span class="dropdown-header"><%- i18n('audit-log', 'certificate') %> #<%- id %></span>
|
||||
<% if (provider === 'letsencrypt') { %>
|
||||
<a href="#" class="renew dropdown-item"><i class="dropdown-icon fe fe-refresh-cw"></i> <%- i18n('certificates', 'force-renew') %></a>
|
||||
<a href="#" class="download dropdown-item"><i class="dropdown-icon fe fe-download"></i> <%- i18n('certificates', 'download') %></a>
|
||||
<% if (meta.dns_challenge === false) { %>
|
||||
<a href="#" class="test dropdown-item"><i class="dropdown-icon fe fe-globe"></i> <%- i18n('certificates', 'test-reachability') %></a>
|
||||
<% } %>
|
||||
<div class="dropdown-divider"></div>
|
||||
<% } %>
|
||||
<a href="#" class="delete dropdown-item"><i class="dropdown-icon fe fe-trash-2"></i> <%- i18n('str', 'delete') %></a>
|
||||
|
@ -2,7 +2,7 @@ const Mn = require('backbone.marionette');
|
||||
const moment = require('moment');
|
||||
const App = require('../../../main');
|
||||
const template = require('./item.ejs');
|
||||
const dns_providers = require('../../../../../../global/certbot-dns-plugins')
|
||||
const dns_providers = require('../../../../../../global/certbot-dns-plugins');
|
||||
|
||||
module.exports = Mn.View.extend({
|
||||
template: template,
|
||||
@ -11,7 +11,9 @@ module.exports = Mn.View.extend({
|
||||
ui: {
|
||||
host_link: '.host-link',
|
||||
renew: 'a.renew',
|
||||
delete: 'a.delete'
|
||||
delete: 'a.delete',
|
||||
download: 'a.download',
|
||||
test: 'a.test'
|
||||
},
|
||||
|
||||
events: {
|
||||
@ -29,7 +31,17 @@ module.exports = Mn.View.extend({
|
||||
e.preventDefault();
|
||||
let win = window.open($(e.currentTarget).attr('rel'), '_blank');
|
||||
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: {
|
||||
|
15
frontend/js/app/nginx/certificates/test.ejs
Normal file
15
frontend/js/app/nginx/certificates/test.ejs
Normal file
@ -0,0 +1,15 @@
|
||||
<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>
|
75
frontend/js/app/nginx/certificates/test.js
Normal file
75
frontend/js/app/nginx/certificates/test.js
Normal file
@ -0,0 +1,75 @@
|
||||
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);
|
||||
});
|
||||
}
|
||||
});
|
@ -257,16 +257,17 @@
|
||||
<div role="tabpanel" class="tab-pane" id="advanced">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<p>Nginx variables available to you are:</p>
|
||||
<p><%- i18n('all-hosts', 'advanced-config-var-headline') %></p>
|
||||
<ul class="text-monospace">
|
||||
<li>$server # Host/IP</li>
|
||||
<li>$port # Port Number</li>
|
||||
<li>$forward_scheme # http or https</li>
|
||||
<li><code>$server</code> <%- i18n('proxy-hosts', 'forward-host') %></li>
|
||||
<li><code>$port</code> <%- i18n('proxy-hosts', 'forward-port') %></li>
|
||||
<li><code>$forward_scheme</code> <%- i18n('proxy-hosts', 'forward-scheme') %></li>
|
||||
</ul>
|
||||
<div class="form-group mb-0">
|
||||
<label class="form-label"><%- i18n('all-hosts', 'advanced-config') %></label>
|
||||
<textarea name="advanced_config" rows="8" class="form-control text-monospace" placeholder="# <%- i18n('all-hosts', 'advanced-warning') %>"><%- advanced_config %></textarea>
|
||||
</div>
|
||||
<p class="small text-gray"><i class="fe fe-alert-triangle"></i> <%- i18n('all-hosts', 'advanced-config-header-info') %></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -278,7 +278,7 @@ module.exports = Mn.View.extend({
|
||||
text: input
|
||||
};
|
||||
},
|
||||
createFilter: /^(?:\.)?(?:[^.*]+\.?)+[^.]$/
|
||||
createFilter: /^(?:\*\.)?(?:[^.*]+\.?)+[^.]$/
|
||||
});
|
||||
|
||||
// Access Lists
|
||||
|
@ -14,8 +14,8 @@
|
||||
</div>
|
||||
<div class="col-sm-8 col-md-8">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%- i18n('streams', 'forward-ip') %><span class="form-required">*</span></label>
|
||||
<input type="text" name="forward_ip" class="form-control text-monospace" placeholder="000.000.000.000" value="<%- forward_ip %>" autocomplete="off" maxlength="15" required>
|
||||
<label class="form-label"><%- i18n('streams', 'forwarding-host') %><span class="form-required">*</span></label>
|
||||
<input type="text" name="forwarding_host" class="form-control text-monospace" placeholder="example.com or 10.0.0.1 or 2001:db8:3333:4444:5555:6666:7777:8888" value="<%- forwarding_host %>" autocomplete="off" maxlength="255" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 col-md-4">
|
||||
|
@ -13,7 +13,7 @@ module.exports = Mn.View.extend({
|
||||
|
||||
ui: {
|
||||
form: 'form',
|
||||
forward_ip: 'input[name="forward_ip"]',
|
||||
forwarding_host: 'input[name="forwarding_host"]',
|
||||
type_error: '.forward-type-error',
|
||||
buttons: '.modal-footer button',
|
||||
switches: '.custom-switch-input',
|
||||
@ -76,13 +76,6 @@ module.exports = Mn.View.extend({
|
||||
}
|
||||
},
|
||||
|
||||
onRender: function () {
|
||||
this.ui.forward_ip.mask('099.099.099.099', {
|
||||
clearIfNotMatch: true,
|
||||
placeholder: '000.000.000.000'
|
||||
});
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
if (typeof options.model === 'undefined' || !options.model) {
|
||||
this.model = new StreamModel.Model();
|
||||
|
@ -12,7 +12,7 @@
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="text-monospace"><%- forward_ip %>:<%- forwarding_port %></div>
|
||||
<div class="text-monospace"><%- forwarding_host %>:<%- forwarding_port %></div>
|
||||
</td>
|
||||
<td>
|
||||
<div>
|
||||
|
@ -1,5 +1,8 @@
|
||||
<div class="container">
|
||||
<div class="d-flex">
|
||||
<button class="navbar-toggler d-lg-none mr-2" type="button" data-toggle="collapse" data-target="#menu">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="/">
|
||||
<img src="/images/favicons/favicon-32x32.png" border="0"> <%- i18n('main', 'app') %>
|
||||
</a>
|
||||
|
@ -1,9 +1,11 @@
|
||||
<div class="page-main">
|
||||
<div class="header" id="header">
|
||||
<!-- Header View -->
|
||||
</div>
|
||||
<div id="menu">
|
||||
<!-- Menu View -->
|
||||
<div class="navbar-light">
|
||||
<div class="header" id="header">
|
||||
<!-- Header View -->
|
||||
</div>
|
||||
<div id="menu">
|
||||
<!-- Menu View -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-3 my-md-5">
|
||||
<div id="app-content" class="container">
|
||||
|
@ -60,7 +60,7 @@
|
||||
},
|
||||
"footer": {
|
||||
"fork-me": "Fork me on Github",
|
||||
"copy": "© 2019 <a href=\"{url}\" target=\"_blank\">jc21.com</a>.",
|
||||
"copy": "© 2021 <a href=\"{url}\" target=\"_blank\">jc21.com</a>.",
|
||||
"theme": "Theme by <a href=\"{url}\" target=\"_blank\">Tabler</a>"
|
||||
},
|
||||
"dashboard": {
|
||||
@ -84,6 +84,8 @@
|
||||
"advanced": "Advanced",
|
||||
"advanced-warning": "Enter your custom Nginx configuration here at your own risk!",
|
||||
"advanced-config": "Custom Nginx Configuration",
|
||||
"advanced-config-var-headline": "These proxy details are available as nginx variables:",
|
||||
"advanced-config-header-info": "Please note, that any add_header or set_header directives added here will not be used by nginx. You will have to add a custom location '/' and add the header in the custom config there.",
|
||||
"hsts-enabled": "HSTS Enabled",
|
||||
"hsts-subdomains": "HSTS Subdomains",
|
||||
"locations": "Custom locations"
|
||||
@ -130,7 +132,7 @@
|
||||
"access-list": "Access List",
|
||||
"allow-websocket-upgrade": "Websockets Support",
|
||||
"ignore-invalid-upstream-ssl": "Ignore Invalid SSL",
|
||||
"custom-forward-host-help": "Use 1.1.1.1/path for sub-folder forwarding"
|
||||
"custom-forward-host-help": "Add a path for sub-folder forwarding.\nExample: 203.0.113.25/path"
|
||||
},
|
||||
"redirection-hosts": {
|
||||
"title": "Redirection Hosts",
|
||||
@ -141,7 +143,7 @@
|
||||
"forward-http-status-code": "HTTP Code",
|
||||
"forward-domain": "Forward Domain",
|
||||
"preserve-path": "Preserve Path",
|
||||
"delete": "Delete Proxy Host",
|
||||
"delete": "Delete Redirection Host",
|
||||
"delete-confirm": "Are you sure you want to delete the Redirection host for: <strong>{domains}</strong>?",
|
||||
"help-title": "What is a Redirection Host?",
|
||||
"help-content": "A Redirection Host will redirect requests from the incoming domain and push the viewer to another domain.\nThe most common reason to use this type of host is when your website changes domains but you still have search engine or referrer links pointing to the old domain."
|
||||
@ -162,7 +164,7 @@
|
||||
"add": "Add Stream",
|
||||
"form-title": "{id, select, undefined{New} other{Edit}} Stream",
|
||||
"incoming-port": "Incoming Port",
|
||||
"forward-ip": "Forward IP",
|
||||
"forwarding-host": "Forward Host",
|
||||
"forwarding-port": "Forward Port",
|
||||
"tcp-forwarding": "TCP Forwarding",
|
||||
"udp-forwarding": "UDP Forwarding",
|
||||
@ -188,6 +190,17 @@
|
||||
"other-certificate-key": "Certificate Key",
|
||||
"other-intermediate-certificate": "Intermediate Certificate",
|
||||
"force-renew": "Renew Now",
|
||||
"test-reachability": "Test Server Reachability",
|
||||
"reachability-title": "Test Server Reachability",
|
||||
"reachability-info": "Test whether the domains are reachable from the public internet using Site24x7. This is not necessary when using the DNS Challenge.",
|
||||
"reachability-failed-to-reach-api": "Communication with the API failed, is NPM running correctly?",
|
||||
"reachability-failed-to-check": "Failed to check the reachability due to a communication error with site24x7.com.",
|
||||
"reachability-ok": "Your server is reachable and creating certificates should be possible.",
|
||||
"reachability-404": "There is a server found at this domain but it does not seem to be Nginx Proxy Manager. Please make sure your domain points to the IP where your NPM instance is running.",
|
||||
"reachability-not-resolved": "There is no server available at this domain. Please make sure your domain exists and points to the IP where your NPM instance is running and if necessary port 80 is forwarded in your router.",
|
||||
"reachability-wrong-data": "There is a server found at this domain but it returned an unexpected data. Is it the NPM server? Please make sure your domain points to the IP where your NPM instance is running.",
|
||||
"reachability-other": "There is a server found at this domain but it returned an unexpected status code {code}. Is it the NPM server? Please make sure your domain points to the IP where your NPM instance is running.",
|
||||
"download": "Download",
|
||||
"renew-title": "Renew Let'sEncrypt Certificate"
|
||||
},
|
||||
"access-lists": {
|
||||
|
@ -9,7 +9,7 @@ const model = Backbone.Model.extend({
|
||||
created_on: null,
|
||||
modified_on: null,
|
||||
incoming_port: null,
|
||||
forward_ip: null,
|
||||
forwarding_host: null,
|
||||
forwarding_port: null,
|
||||
tcp_forwarding: true,
|
||||
udp_forwarding: false,
|
||||
|
@ -7,7 +7,6 @@
|
||||
"@babel/core": "^7.9.0",
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-loader": "^8.1.0",
|
||||
"babel-minify-webpack-plugin": "^0.3.1",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"backbone": "^1.4.0",
|
||||
"backbone.marionette": "^4.1.2",
|
||||
@ -28,10 +27,10 @@
|
||||
"messageformat-loader": "^0.8.1",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"moment": "^2.24.0",
|
||||
"node-sass": "^4.13.1",
|
||||
"node-sass": "^6.0.1",
|
||||
"nodemon": "^2.0.2",
|
||||
"numeral": "^2.0.6",
|
||||
"sass-loader": "^8.0.2",
|
||||
"sass-loader": "10.2.0",
|
||||
"style-loader": "^1.1.3",
|
||||
"tabler-ui": "git+https://github.com/tabler/tabler.git#00f78ad823311bc3ad974ac3e5b0126198f0a813",
|
||||
"underscore": "^1.12.1",
|
||||
|
@ -13,8 +13,8 @@ module.exports = {
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: 'js/[name].bundle.js',
|
||||
chunkFilename: 'js/[name].bundle.[id].js',
|
||||
filename: `js/[name].bundle.js?v=${PACKAGE.version}`,
|
||||
chunkFilename: `js/[name].bundle.[id].js?v=${PACKAGE.version}`,
|
||||
publicPath: '/'
|
||||
},
|
||||
resolve: {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,10 +9,10 @@
|
||||
* cloudflare: {
|
||||
* display_name: "Name displayed to the user",
|
||||
* package_name: "Package name in PyPi repo",
|
||||
* package_version: "Package version in PyPi repo",
|
||||
* version_requirement: "Optional package version requirements (e.g. ==1.3 or >=1.2,<2.0, see https://www.python.org/dev/peps/pep-0440/#version-specifiers)",
|
||||
* dependencies: "Additional dependencies, space separated (as you would pass it to pip install)",
|
||||
* credentials: `Template of the credentials file`,
|
||||
* full_plugin_name: "The full plugin name as used in the commandline with certbot, including prefixes, e.g. 'certbot-dns-njalla:dns-njalla'",
|
||||
* full_plugin_name: "The full plugin name as used in the commandline with certbot, e.g. 'dns-njalla'",
|
||||
* },
|
||||
* ...
|
||||
* }
|
||||
@ -22,30 +22,30 @@
|
||||
module.exports = {
|
||||
//####################################################//
|
||||
acmedns: {
|
||||
display_name: 'ACME-DNS',
|
||||
package_name: 'certbot-dns-acmedns',
|
||||
package_version: '0.1.0',
|
||||
dependencies: '',
|
||||
credentials: `certbot_dns_acmedns:dns_acmedns_api_url = http://acmedns-server/
|
||||
certbot_dns_acmedns:dns_acmedns_registration_file = /data/acme-registration.json`,
|
||||
full_plugin_name: 'certbot-dns-acmedns:dns-acmedns',
|
||||
display_name: 'ACME-DNS',
|
||||
package_name: 'certbot-dns-acmedns',
|
||||
version_requirement: '~=0.1.0',
|
||||
dependencies: '',
|
||||
credentials: `dns_acmedns_api_url = http://acmedns-server/
|
||||
dns_acmedns_registration_file = /data/acme-registration.json`,
|
||||
full_plugin_name: 'dns-acmedns',
|
||||
},
|
||||
aliyun: {
|
||||
display_name: 'Aliyun',
|
||||
package_name: 'certbot-dns-aliyun',
|
||||
package_version: '0.38.1',
|
||||
dependencies: '',
|
||||
credentials: `certbot_dns_aliyun:dns_aliyun_access_key = 12345678
|
||||
certbot_dns_aliyun:dns_aliyun_access_key_secret = 1234567890abcdef1234567890abcdef`,
|
||||
full_plugin_name: 'certbot-dns-aliyun:dns-aliyun',
|
||||
display_name: 'Aliyun',
|
||||
package_name: 'certbot-dns-aliyun',
|
||||
version_requirement: '~=0.38.1',
|
||||
dependencies: '',
|
||||
credentials: `dns_aliyun_access_key = 12345678
|
||||
dns_aliyun_access_key_secret = 1234567890abcdef1234567890abcdef`,
|
||||
full_plugin_name: 'dns-aliyun',
|
||||
},
|
||||
//####################################################//
|
||||
azure: {
|
||||
display_name: 'Azure',
|
||||
package_name: 'certbot-dns-azure',
|
||||
package_version: '1.2.0',
|
||||
dependencies: '',
|
||||
credentials: `# This plugin supported API authentication using either Service Principals or utilizing a Managed Identity assigned to the virtual machine.
|
||||
display_name: 'Azure',
|
||||
package_name: 'certbot-dns-azure',
|
||||
version_requirement: '~=1.2.0',
|
||||
dependencies: '',
|
||||
credentials: `# This plugin supported API authentication using either Service Principals or utilizing a Managed Identity assigned to the virtual machine.
|
||||
# Regardless which authentication method used, the identity will need the “DNS Zone Contributor” role assigned to it.
|
||||
# As multiple Azure DNS Zones in multiple resource groups can exist, the config file needs a mapping of zone to resource group ID. Multiple zones -> ID mappings can be listed by using the key dns_azure_zoneX where X is a unique number. At least 1 zone mapping is required.
|
||||
|
||||
@ -67,165 +67,179 @@ dns_azure_zone2 = example.org:/subscriptions/99800903-fb14-4992-9aff-12eaf274462
|
||||
},
|
||||
//####################################################//
|
||||
cloudflare: {
|
||||
display_name: 'Cloudflare',
|
||||
package_name: 'certbot-dns-cloudflare',
|
||||
package_version: '1.8.0',
|
||||
dependencies: 'cloudflare',
|
||||
credentials: `# Cloudflare API token
|
||||
display_name: 'Cloudflare',
|
||||
package_name: 'certbot-dns-cloudflare',
|
||||
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
|
||||
dependencies: 'cloudflare',
|
||||
credentials: `# Cloudflare API token
|
||||
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567`,
|
||||
full_plugin_name: 'dns-cloudflare',
|
||||
},
|
||||
//####################################################//
|
||||
cloudns: {
|
||||
display_name: 'ClouDNS',
|
||||
package_name: 'certbot-dns-cloudns',
|
||||
package_version: '0.4.0',
|
||||
dependencies: '',
|
||||
credentials: `# Target user ID (see https://www.cloudns.net/api-settings/)
|
||||
display_name: 'ClouDNS',
|
||||
package_name: 'certbot-dns-cloudns',
|
||||
version_requirement: '~=0.4.0',
|
||||
dependencies: '',
|
||||
credentials: `# Target user ID (see https://www.cloudns.net/api-settings/)
|
||||
dns_cloudns_auth_id=1234
|
||||
# Alternatively, one of the following two options can be set:
|
||||
# dns_cloudns_sub_auth_id=1234
|
||||
# dns_cloudns_sub_auth_user=foobar
|
||||
|
||||
# dns_cloudns_sub_auth_user=foobar
|
||||
|
||||
# API password
|
||||
dns_cloudns_auth_password=password1`,
|
||||
full_plugin_name: 'dns-cloudns',
|
||||
},
|
||||
//####################################################//
|
||||
cloudxns: {
|
||||
display_name: 'CloudXNS',
|
||||
package_name: 'certbot-dns-cloudxns',
|
||||
package_version: '1.8.0',
|
||||
dependencies: '',
|
||||
credentials: `dns_cloudxns_api_key = 1234567890abcdef1234567890abcdef
|
||||
display_name: 'CloudXNS',
|
||||
package_name: 'certbot-dns-cloudxns',
|
||||
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
|
||||
dependencies: '',
|
||||
credentials: `dns_cloudxns_api_key = 1234567890abcdef1234567890abcdef
|
||||
dns_cloudxns_secret_key = 1122334455667788`,
|
||||
full_plugin_name: 'dns-cloudxns',
|
||||
},
|
||||
//####################################################//
|
||||
corenetworks: {
|
||||
display_name: 'Core Networks',
|
||||
package_name: 'certbot-dns-corenetworks',
|
||||
package_version: '0.1.4',
|
||||
dependencies: '',
|
||||
credentials: `certbot_dns_corenetworks:dns_corenetworks_username = asaHB12r
|
||||
certbot_dns_corenetworks:dns_corenetworks_password = secure_password`,
|
||||
full_plugin_name: 'certbot-dns-corenetworks:dns-corenetworks',
|
||||
display_name: 'Core Networks',
|
||||
package_name: 'certbot-dns-corenetworks',
|
||||
version_requirement: '~=0.1.4',
|
||||
dependencies: '',
|
||||
credentials: `dns_corenetworks_username = asaHB12r
|
||||
dns_corenetworks_password = secure_password`,
|
||||
full_plugin_name: 'dns-corenetworks',
|
||||
},
|
||||
//####################################################//
|
||||
cpanel: {
|
||||
display_name: 'cPanel',
|
||||
package_name: 'certbot-dns-cpanel',
|
||||
package_version: '0.2.2',
|
||||
dependencies: '',
|
||||
credentials: `certbot_dns_cpanel:cpanel_url = https://cpanel.example.com:2083
|
||||
certbot_dns_cpanel:cpanel_username = user
|
||||
certbot_dns_cpanel:cpanel_password = hunter2`,
|
||||
full_plugin_name: 'certbot-dns-cpanel:cpanel',
|
||||
display_name: 'cPanel',
|
||||
package_name: 'certbot-dns-cpanel',
|
||||
version_requirement: '~=0.2.2',
|
||||
dependencies: '',
|
||||
credentials: `cpanel_url = https://cpanel.example.com:2083
|
||||
cpanel_username = user
|
||||
cpanel_password = hunter2`,
|
||||
full_plugin_name: 'cpanel',
|
||||
},
|
||||
//####################################################//
|
||||
desec: {
|
||||
display_name: 'deSEC',
|
||||
package_name: 'certbot-dns-desec',
|
||||
version_requirement: '~=0.3.0',
|
||||
dependencies: '',
|
||||
credentials: `dns_desec_token = YOUR_DESEC_API_TOKEN
|
||||
dns_desec_endpoint = https://desec.io/api/v1/`,
|
||||
full_plugin_name: 'dns-desec',
|
||||
},
|
||||
//####################################################//
|
||||
duckdns: {
|
||||
display_name: 'DuckDNS',
|
||||
package_name: 'certbot-dns-duckdns',
|
||||
package_version: '0.6',
|
||||
dependencies: '',
|
||||
credentials: 'dns_duckdns_token=your-duckdns-token',
|
||||
full_plugin_name: 'dns-duckdns',
|
||||
display_name: 'DuckDNS',
|
||||
package_name: 'certbot-dns-duckdns',
|
||||
version_requirement: '~=0.6',
|
||||
dependencies: '',
|
||||
credentials: 'dns_duckdns_token=your-duckdns-token',
|
||||
full_plugin_name: 'dns-duckdns',
|
||||
},
|
||||
//####################################################//
|
||||
digitalocean: {
|
||||
display_name: 'DigitalOcean',
|
||||
package_name: 'certbot-dns-digitalocean',
|
||||
package_version: '1.8.0',
|
||||
dependencies: '',
|
||||
credentials: 'dns_digitalocean_token = 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff',
|
||||
full_plugin_name: 'dns-digitalocean',
|
||||
display_name: 'DigitalOcean',
|
||||
package_name: 'certbot-dns-digitalocean',
|
||||
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
|
||||
dependencies: '',
|
||||
credentials: 'dns_digitalocean_token = 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff',
|
||||
full_plugin_name: 'dns-digitalocean',
|
||||
},
|
||||
//####################################################//
|
||||
directadmin: {
|
||||
display_name: 'DirectAdmin',
|
||||
package_name: 'certbot-dns-directadmin',
|
||||
package_version: '0.0.20',
|
||||
dependencies: '',
|
||||
credentials: `directadmin_url = https://my.directadminserver.com:2222
|
||||
display_name: 'DirectAdmin',
|
||||
package_name: 'certbot-dns-directadmin',
|
||||
version_requirement: '~=0.0.23',
|
||||
dependencies: '',
|
||||
credentials: `directadmin_url = https://my.directadminserver.com:2222
|
||||
directadmin_username = username
|
||||
directadmin_password = aSuperStrongPassword`,
|
||||
full_plugin_name: 'certbot-dns-directadmin:directadmin',
|
||||
full_plugin_name: 'directadmin',
|
||||
},
|
||||
//####################################################//
|
||||
dnsimple: {
|
||||
display_name: 'DNSimple',
|
||||
package_name: 'certbot-dns-dnsimple',
|
||||
package_version: '1.8.0',
|
||||
dependencies: '',
|
||||
credentials: 'dns_dnsimple_token = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw',
|
||||
full_plugin_name: 'dns-dnsimple',
|
||||
display_name: 'DNSimple',
|
||||
package_name: 'certbot-dns-dnsimple',
|
||||
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
|
||||
dependencies: '',
|
||||
credentials: 'dns_dnsimple_token = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw',
|
||||
full_plugin_name: 'dns-dnsimple',
|
||||
},
|
||||
//####################################################//
|
||||
dnsmadeeasy: {
|
||||
display_name: 'DNS Made Easy',
|
||||
package_name: 'certbot-dns-dnsmadeeasy',
|
||||
package_version: '1.8.0',
|
||||
dependencies: '',
|
||||
credentials: `dns_dnsmadeeasy_api_key = 1c1a3c91-4770-4ce7-96f4-54c0eb0e457a
|
||||
display_name: 'DNS Made Easy',
|
||||
package_name: 'certbot-dns-dnsmadeeasy',
|
||||
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
|
||||
dependencies: '',
|
||||
credentials: `dns_dnsmadeeasy_api_key = 1c1a3c91-4770-4ce7-96f4-54c0eb0e457a
|
||||
dns_dnsmadeeasy_secret_key = c9b5625f-9834-4ff8-baba-4ed5f32cae55`,
|
||||
full_plugin_name: 'dns-dnsmadeeasy',
|
||||
},
|
||||
//####################################################//
|
||||
dnspod: {
|
||||
display_name: 'DNSPod',
|
||||
package_name: 'certbot-dns-dnspod',
|
||||
package_version: '0.1.0',
|
||||
dependencies: '',
|
||||
credentials: `certbot_dns_dnspod:dns_dnspod_email = "DNSPOD-API-REQUIRES-A-VALID-EMAIL"
|
||||
certbot_dns_dnspod:dns_dnspod_api_token = "DNSPOD-API-TOKEN"`,
|
||||
full_plugin_name: 'certbot-dns-dnspod:dns-dnspod',
|
||||
display_name: 'DNSPod',
|
||||
package_name: 'certbot-dns-dnspod',
|
||||
version_requirement: '~=0.1.0',
|
||||
dependencies: '',
|
||||
credentials: `dns_dnspod_email = "DNSPOD-API-REQUIRES-A-VALID-EMAIL"
|
||||
dns_dnspod_api_token = "DNSPOD-API-TOKEN"`,
|
||||
full_plugin_name: 'dns-dnspod',
|
||||
},
|
||||
//####################################################//
|
||||
dynu: {
|
||||
display_name: 'Dynu',
|
||||
package_name: 'certbot-dns-dynu',
|
||||
package_version: '0.0.1',
|
||||
dependencies: '',
|
||||
credentials: 'certbot_dns_dynu:dns_dynu_auth_token = YOUR_DYNU_AUTH_TOKEN',
|
||||
full_plugin_name: 'certbot-dns-dynu:dns-dynu',
|
||||
display_name: 'Dynu',
|
||||
package_name: 'certbot-dns-dynu',
|
||||
version_requirement: '~=0.0.1',
|
||||
dependencies: '',
|
||||
credentials: 'dns_dynu_auth_token = YOUR_DYNU_AUTH_TOKEN',
|
||||
full_plugin_name: 'dns-dynu',
|
||||
},
|
||||
//####################################################//
|
||||
eurodns: {
|
||||
display_name: 'EuroDNS',
|
||||
package_name: 'certbot-dns-eurodns',
|
||||
package_version: '0.0.4',
|
||||
dependencies: '',
|
||||
credentials: `dns_eurodns_applicationId = myuser
|
||||
display_name: 'EuroDNS',
|
||||
package_name: 'certbot-dns-eurodns',
|
||||
version_requirement: '~=0.0.4',
|
||||
dependencies: '',
|
||||
credentials: `dns_eurodns_applicationId = myuser
|
||||
dns_eurodns_apiKey = mysecretpassword
|
||||
dns_eurodns_endpoint = https://rest-api.eurodns.com/user-api-gateway/proxy`,
|
||||
full_plugin_name: 'certbot-dns-eurodns:dns-eurodns',
|
||||
full_plugin_name: 'dns-eurodns',
|
||||
},
|
||||
//####################################################//
|
||||
gandi: {
|
||||
display_name: 'Gandi Live DNS',
|
||||
package_name: 'certbot_plugin_gandi',
|
||||
package_version: '1.2.5',
|
||||
dependencies: '',
|
||||
credentials: 'certbot_plugin_gandi:dns_api_key = APIKEY',
|
||||
full_plugin_name: 'certbot-plugin-gandi:dns',
|
||||
display_name: 'Gandi Live DNS',
|
||||
package_name: 'certbot_plugin_gandi',
|
||||
version_requirement: '~=1.3.2',
|
||||
dependencies: '',
|
||||
credentials: `# live dns v5 api key
|
||||
dns_gandi_api_key=APIKEY
|
||||
|
||||
# optional organization id, remove it if not used
|
||||
dns_gandi_sharing_id=SHARINGID`,
|
||||
full_plugin_name: 'dns-gandi',
|
||||
},
|
||||
//####################################################//
|
||||
godaddy: {
|
||||
display_name: 'GoDaddy',
|
||||
package_name: 'certbot-dns-godaddy',
|
||||
package_version: '0.2.0',
|
||||
dependencies: '',
|
||||
credentials: `dns_godaddy_secret = 0123456789abcdef0123456789abcdef01234567
|
||||
display_name: 'GoDaddy',
|
||||
package_name: 'certbot-dns-godaddy',
|
||||
version_requirement: '~=0.2.0',
|
||||
dependencies: '',
|
||||
credentials: `dns_godaddy_secret = 0123456789abcdef0123456789abcdef01234567
|
||||
dns_godaddy_key = abcdef0123456789abcdef01234567abcdef0123`,
|
||||
full_plugin_name: 'dns-godaddy',
|
||||
},
|
||||
//####################################################//
|
||||
google: {
|
||||
display_name: 'Google',
|
||||
package_name: 'certbot-dns-google',
|
||||
package_version: '1.8.0',
|
||||
dependencies: '',
|
||||
credentials: `{
|
||||
display_name: 'Google',
|
||||
package_name: 'certbot-dns-google',
|
||||
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
|
||||
dependencies: '',
|
||||
credentials: `{
|
||||
"type": "service_account",
|
||||
...
|
||||
}`,
|
||||
@ -233,122 +247,156 @@ dns_godaddy_key = abcdef0123456789abcdef01234567abcdef0123`,
|
||||
},
|
||||
//####################################################//
|
||||
hetzner: {
|
||||
display_name: 'Hetzner',
|
||||
package_name: 'certbot-dns-hetzner',
|
||||
package_version: '1.0.4',
|
||||
dependencies: '',
|
||||
credentials: 'certbot_dns_hetzner:dns_hetzner_api_token = 0123456789abcdef0123456789abcdef',
|
||||
full_plugin_name: 'certbot-dns-hetzner:dns-hetzner',
|
||||
display_name: 'Hetzner',
|
||||
package_name: 'certbot-dns-hetzner',
|
||||
version_requirement: '~=1.0.4',
|
||||
dependencies: '',
|
||||
credentials: 'dns_hetzner_api_token = 0123456789abcdef0123456789abcdef',
|
||||
full_plugin_name: 'dns-hetzner',
|
||||
},
|
||||
//####################################################//
|
||||
infomaniak: {
|
||||
display_name: 'Infomaniak',
|
||||
package_name: 'certbot-dns-infomaniak',
|
||||
package_version: '0.1.12',
|
||||
dependencies: '',
|
||||
credentials: 'certbot_dns_infomaniak:dns_infomaniak_token = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
full_plugin_name: 'certbot-dns-infomaniak:dns-infomaniak',
|
||||
display_name: 'Infomaniak',
|
||||
package_name: 'certbot-dns-infomaniak',
|
||||
version_requirement: '~=0.1.12',
|
||||
dependencies: '',
|
||||
credentials: 'dns_infomaniak_token = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
full_plugin_name: 'dns-infomaniak',
|
||||
},
|
||||
//####################################################//
|
||||
inwx: {
|
||||
display_name: 'INWX',
|
||||
package_name: 'certbot-dns-inwx',
|
||||
package_version: '2.1.2',
|
||||
dependencies: '',
|
||||
credentials: `certbot_dns_inwx:dns_inwx_url = https://api.domrobot.com/xmlrpc/
|
||||
certbot_dns_inwx:dns_inwx_username = your_username
|
||||
certbot_dns_inwx:dns_inwx_password = your_password
|
||||
certbot_dns_inwx:dns_inwx_shared_secret = your_shared_secret optional`,
|
||||
full_plugin_name: 'certbot-dns-inwx:dns-inwx',
|
||||
display_name: 'INWX',
|
||||
package_name: 'certbot-dns-inwx',
|
||||
version_requirement: '~=2.1.2',
|
||||
dependencies: '',
|
||||
credentials: `dns_inwx_url = https://api.domrobot.com/xmlrpc/
|
||||
dns_inwx_username = your_username
|
||||
dns_inwx_password = your_password
|
||||
dns_inwx_shared_secret = your_shared_secret optional`,
|
||||
full_plugin_name: 'dns-inwx',
|
||||
},
|
||||
//####################################################//
|
||||
ionos: {
|
||||
display_name: 'IONOS',
|
||||
package_name: 'certbot-dns-ionos',
|
||||
package_version: '0.0.7',
|
||||
dependencies: '',
|
||||
credentials: `certbot_dns_ionos:dns_ionos_prefix = myapikeyprefix
|
||||
certbot_dns_ionos:dns_ionos_secret = verysecureapikeysecret
|
||||
certbot_dns_ionos:dns_ionos_endpoint = https://api.hosting.ionos.com`,
|
||||
full_plugin_name: 'certbot-dns-ionos:dns-ionos',
|
||||
display_name: 'IONOS',
|
||||
package_name: 'certbot-dns-ionos',
|
||||
version_requirement: '==2021.9.20.post1',
|
||||
dependencies: '',
|
||||
credentials: `dns_ionos_prefix = myapikeyprefix
|
||||
dns_ionos_secret = verysecureapikeysecret
|
||||
dns_ionos_endpoint = https://api.hosting.ionos.com`,
|
||||
full_plugin_name: 'dns-ionos',
|
||||
},
|
||||
//####################################################//
|
||||
ispconfig: {
|
||||
display_name: 'ISPConfig',
|
||||
package_name: 'certbot-dns-ispconfig',
|
||||
package_version: '0.2.0',
|
||||
dependencies: '',
|
||||
credentials: `certbot_dns_ispconfig:dns_ispconfig_username = myremoteuser
|
||||
certbot_dns_ispconfig:dns_ispconfig_password = verysecureremoteuserpassword
|
||||
certbot_dns_ispconfig:dns_ispconfig_endpoint = https://localhost:8080`,
|
||||
full_plugin_name: 'certbot-dns-ispconfig:dns-ispconfig',
|
||||
display_name: 'ISPConfig',
|
||||
package_name: 'certbot-dns-ispconfig',
|
||||
version_requirement: '~=0.2.0',
|
||||
dependencies: '',
|
||||
credentials: `dns_ispconfig_username = myremoteuser
|
||||
dns_ispconfig_password = verysecureremoteuserpassword
|
||||
dns_ispconfig_endpoint = https://localhost:8080`,
|
||||
full_plugin_name: 'dns-ispconfig',
|
||||
},
|
||||
//####################################################//
|
||||
isset: {
|
||||
display_name: 'Isset',
|
||||
package_name: 'certbot-dns-isset',
|
||||
package_version: '0.0.3',
|
||||
dependencies: '',
|
||||
credentials: `certbot_dns_isset:dns_isset_endpoint="https://customer.isset.net/api"
|
||||
certbot_dns_isset:dns_isset_token="<token>"`,
|
||||
full_plugin_name: 'certbot-dns-isset:dns-isset',
|
||||
display_name: 'Isset',
|
||||
package_name: 'certbot-dns-isset',
|
||||
version_requirement: '~=0.0.3',
|
||||
dependencies: '',
|
||||
credentials: `dns_isset_endpoint="https://customer.isset.net/api"
|
||||
dns_isset_token="<token>"`,
|
||||
full_plugin_name: 'dns-isset',
|
||||
},
|
||||
joker: {
|
||||
display_name: 'Joker',
|
||||
package_name: 'certbot-dns-joker',
|
||||
version_requirement: '~=1.1.0',
|
||||
dependencies: '',
|
||||
credentials: `dns_joker_username = <Dynamic DNS Authentication Username>
|
||||
dns_joker_password = <Dynamic DNS Authentication Password>
|
||||
dns_joker_domain = <Dynamic DNS Domain>`,
|
||||
full_plugin_name: 'dns-joker',
|
||||
},
|
||||
//####################################################//
|
||||
linode: {
|
||||
display_name: 'Linode',
|
||||
package_name: 'certbot-dns-linode',
|
||||
package_version: '1.8.0',
|
||||
dependencies: '',
|
||||
credentials: `dns_linode_key = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ64
|
||||
display_name: 'Linode',
|
||||
package_name: 'certbot-dns-linode',
|
||||
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
|
||||
dependencies: '',
|
||||
credentials: `dns_linode_key = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ64
|
||||
dns_linode_version = [<blank>|3|4]`,
|
||||
full_plugin_name: 'dns-linode',
|
||||
},
|
||||
//####################################################//
|
||||
loopia: {
|
||||
display_name: 'Loopia',
|
||||
package_name: 'certbot-dns-loopia',
|
||||
version_requirement: '~=1.0.0',
|
||||
dependencies: '',
|
||||
credentials: `dns_loopia_user = user@loopiaapi
|
||||
dns_loopia_password = abcdef0123456789abcdef01234567abcdef0123`,
|
||||
full_plugin_name: 'dns-loopia',
|
||||
},
|
||||
//####################################################//
|
||||
luadns: {
|
||||
display_name: 'LuaDNS',
|
||||
package_name: 'certbot-dns-luadns',
|
||||
package_version: '1.8.0',
|
||||
dependencies: '',
|
||||
credentials: `dns_luadns_email = user@example.com
|
||||
display_name: 'LuaDNS',
|
||||
package_name: 'certbot-dns-luadns',
|
||||
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
|
||||
dependencies: '',
|
||||
credentials: `dns_luadns_email = user@example.com
|
||||
dns_luadns_token = 0123456789abcdef0123456789abcdef`,
|
||||
full_plugin_name: 'dns-luadns',
|
||||
},
|
||||
//####################################################//
|
||||
netcup: {
|
||||
display_name: 'netcup',
|
||||
package_name: 'certbot-dns-netcup',
|
||||
package_version: '1.0.0',
|
||||
dependencies: '',
|
||||
credentials: `certbot_dns_netcup:dns_netcup_customer_id = 123456
|
||||
certbot_dns_netcup:dns_netcup_api_key = 0123456789abcdef0123456789abcdef01234567
|
||||
certbot_dns_netcup:dns_netcup_api_password = abcdef0123456789abcdef01234567abcdef0123`,
|
||||
full_plugin_name: 'certbot-dns-netcup:dns-netcup',
|
||||
display_name: 'netcup',
|
||||
package_name: 'certbot-dns-netcup',
|
||||
version_requirement: '~=1.0.0',
|
||||
dependencies: '',
|
||||
credentials: `dns_netcup_customer_id = 123456
|
||||
dns_netcup_api_key = 0123456789abcdef0123456789abcdef01234567
|
||||
dns_netcup_api_password = abcdef0123456789abcdef01234567abcdef0123`,
|
||||
full_plugin_name: 'dns-netcup',
|
||||
},
|
||||
//####################################################//
|
||||
njalla: {
|
||||
display_name: 'Njalla',
|
||||
package_name: 'certbot-dns-njalla',
|
||||
package_version: '1.0.0',
|
||||
dependencies: '',
|
||||
credentials: 'certbot_dns_njalla:dns_njalla_token = 0123456789abcdef0123456789abcdef01234567',
|
||||
full_plugin_name: 'certbot-dns-njalla:dns-njalla',
|
||||
display_name: 'Njalla',
|
||||
package_name: 'certbot-dns-njalla',
|
||||
version_requirement: '~=1.0.0',
|
||||
dependencies: '',
|
||||
credentials: 'dns_njalla_token = 0123456789abcdef0123456789abcdef01234567',
|
||||
full_plugin_name: 'dns-njalla',
|
||||
},
|
||||
//####################################################//
|
||||
nsone: {
|
||||
display_name: 'NS1',
|
||||
package_name: 'certbot-dns-nsone',
|
||||
package_version: '1.8.0',
|
||||
dependencies: '',
|
||||
credentials: 'dns_nsone_api_key = MDAwMDAwMDAwMDAwMDAw',
|
||||
full_plugin_name: 'dns-nsone',
|
||||
display_name: 'NS1',
|
||||
package_name: 'certbot-dns-nsone',
|
||||
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
|
||||
dependencies: '',
|
||||
credentials: 'dns_nsone_api_key = MDAwMDAwMDAwMDAwMDAw',
|
||||
full_plugin_name: 'dns-nsone',
|
||||
},
|
||||
//####################################################//
|
||||
oci: {
|
||||
display_name: 'Oracle Cloud Infrastructure DNS',
|
||||
package_name: 'certbot-dns-oci',
|
||||
package_version: '0.3.6',
|
||||
dependencies: 'oci',
|
||||
credentials: `[DEFAULT]
|
||||
user = ocid1.user.oc1...
|
||||
fingerprint = xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
|
||||
tenancy = ocid1.tenancy.oc1...
|
||||
region = us-ashburn-1
|
||||
key_file = ~/.oci/oci_api_key.pem`,
|
||||
full_plugin_name: 'dns-oci',
|
||||
},
|
||||
//####################################################//
|
||||
ovh: {
|
||||
display_name: 'OVH',
|
||||
package_name: 'certbot-dns-ovh',
|
||||
package_version: '1.8.0',
|
||||
dependencies: '',
|
||||
credentials: `dns_ovh_endpoint = ovh-eu
|
||||
display_name: 'OVH',
|
||||
package_name: 'certbot-dns-ovh',
|
||||
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
|
||||
dependencies: '',
|
||||
credentials: `dns_ovh_endpoint = ovh-eu
|
||||
dns_ovh_application_key = MDAwMDAwMDAwMDAw
|
||||
dns_ovh_application_secret = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
|
||||
dns_ovh_consumer_key = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw`,
|
||||
@ -356,41 +404,41 @@ dns_ovh_consumer_key = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw`,
|
||||
},
|
||||
//####################################################//
|
||||
porkbun: {
|
||||
display_name: 'Porkbun',
|
||||
package_name: 'certbot-dns-porkbun',
|
||||
package_version: '0.2',
|
||||
dependencies: '',
|
||||
credentials: `dns_porkbun_key=your-porkbun-api-key
|
||||
display_name: 'Porkbun',
|
||||
package_name: 'certbot-dns-porkbun',
|
||||
version_requirement: '~=0.2',
|
||||
dependencies: '',
|
||||
credentials: `dns_porkbun_key=your-porkbun-api-key
|
||||
dns_porkbun_secret=your-porkbun-api-secret`,
|
||||
full_plugin_name: 'dns-porkbun',
|
||||
},
|
||||
//####################################################//
|
||||
powerdns: {
|
||||
display_name: 'PowerDNS',
|
||||
package_name: 'certbot-dns-powerdns',
|
||||
package_version: '0.2.0',
|
||||
dependencies: '',
|
||||
credentials: `certbot_dns_powerdns:dns_powerdns_api_url = https://api.mypowerdns.example.org
|
||||
certbot_dns_powerdns:dns_powerdns_api_key = AbCbASsd!@34`,
|
||||
full_plugin_name: 'certbot-dns-powerdns:dns-powerdns',
|
||||
display_name: 'PowerDNS',
|
||||
package_name: 'certbot-dns-powerdns',
|
||||
version_requirement: '~=0.2.0',
|
||||
dependencies: '',
|
||||
credentials: `dns_powerdns_api_url = https://api.mypowerdns.example.org
|
||||
dns_powerdns_api_key = AbCbASsd!@34`,
|
||||
full_plugin_name: 'dns-powerdns',
|
||||
},
|
||||
//####################################################//
|
||||
regru: {
|
||||
display_name: 'reg.ru',
|
||||
package_name: 'certbot-regru',
|
||||
package_version: '1.0.2',
|
||||
dependencies: '',
|
||||
credentials: `certbot_regru:dns_username=username
|
||||
display_name: 'reg.ru',
|
||||
package_name: 'certbot-regru',
|
||||
version_requirement: '~=1.0.2',
|
||||
dependencies: '',
|
||||
credentials: `certbot_regru:dns_username=username
|
||||
certbot_regru:dns_password=password`,
|
||||
full_plugin_name: 'certbot-regru:dns',
|
||||
},
|
||||
//####################################################//
|
||||
rfc2136: {
|
||||
display_name: 'RFC 2136',
|
||||
package_name: 'certbot-dns-rfc2136',
|
||||
package_version: '1.8.0',
|
||||
dependencies: '',
|
||||
credentials: `# Target DNS server
|
||||
display_name: 'RFC 2136',
|
||||
package_name: 'certbot-dns-rfc2136',
|
||||
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
|
||||
dependencies: '',
|
||||
credentials: `# Target DNS server
|
||||
dns_rfc2136_server = 192.0.2.1
|
||||
# Target DNS port
|
||||
dns_rfc2136_port = 53
|
||||
@ -404,32 +452,43 @@ dns_rfc2136_algorithm = HMAC-SHA512`,
|
||||
},
|
||||
//####################################################//
|
||||
route53: {
|
||||
display_name: 'Route 53 (Amazon)',
|
||||
package_name: 'certbot-dns-route53',
|
||||
package_version: '1.8.0',
|
||||
dependencies: '',
|
||||
credentials: `[default]
|
||||
display_name: 'Route 53 (Amazon)',
|
||||
package_name: 'certbot-dns-route53',
|
||||
version_requirement: '==$(certbot --version | grep -Eo \'[0-9](\\.[0-9]+)+\')', // official plugin, use certbot version
|
||||
dependencies: '',
|
||||
credentials: `[default]
|
||||
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
|
||||
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY`,
|
||||
full_plugin_name: 'dns-route53',
|
||||
},
|
||||
//####################################################//
|
||||
transip: {
|
||||
display_name: 'TransIP',
|
||||
package_name: 'certbot-dns-transip',
|
||||
package_version: '0.3.3',
|
||||
dependencies: '',
|
||||
credentials: `certbot_dns_transip:dns_transip_username = my_username
|
||||
certbot_dns_transip:dns_transip_key_file = /etc/letsencrypt/transip-rsa.key`,
|
||||
full_plugin_name: 'certbot-dns-transip:dns-transip',
|
||||
display_name: 'TransIP',
|
||||
package_name: 'certbot-dns-transip',
|
||||
version_requirement: '~=0.3.3',
|
||||
dependencies: '',
|
||||
credentials: `dns_transip_username = my_username
|
||||
dns_transip_key_file = /etc/letsencrypt/transip-rsa.key`,
|
||||
full_plugin_name: 'dns-transip',
|
||||
},
|
||||
//####################################################//
|
||||
vultr: {
|
||||
display_name: 'Vultr',
|
||||
package_name: 'certbot-dns-vultr',
|
||||
package_version: '1.0.3',
|
||||
dependencies: '',
|
||||
credentials: 'certbot_dns_vultr:dns_vultr_key = YOUR_VULTR_API_KEY',
|
||||
full_plugin_name: 'certbot-dns-vultr:dns-vultr',
|
||||
display_name: 'Vultr',
|
||||
package_name: 'certbot-dns-vultr',
|
||||
version_requirement: '~=1.0.3',
|
||||
dependencies: '',
|
||||
credentials: 'dns_vultr_key = YOUR_VULTR_API_KEY',
|
||||
full_plugin_name: 'dns-vultr',
|
||||
},
|
||||
//####################################################//
|
||||
websupportsk: {
|
||||
display_name: 'Websupport.sk',
|
||||
package_name: 'certbot-dns-websupportsk',
|
||||
version_requirement: '~=0.1.6',
|
||||
dependencies: '',
|
||||
credentials: `dns_websupportsk_api_key = <api_key>
|
||||
dns_websupportsk_secret = <secret>
|
||||
dns_websupportsk_domain = example.com`,
|
||||
full_plugin_name: 'dns-websupportsk',
|
||||
},
|
||||
};
|
||||
|
@ -18,10 +18,10 @@ if hash docker-compose 2>/dev/null; then
|
||||
|
||||
if [ "$1" == "-f" ]; then
|
||||
echo -e "${BLUE}❯ ${YELLOW}Following Backend Container:${RESET}"
|
||||
docker logs -f npmdev_npm_1
|
||||
docker logs -f npm_core
|
||||
else
|
||||
echo -e "${YELLOW}Hint:${RESET} You can follow the output of some of the containers with:"
|
||||
echo " docker logs -f npmdev_npm_1"
|
||||
echo " docker logs -f npm_core"
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}❯ docker-compose command is not available${RESET}"
|
||||
|
Reference in New Issue
Block a user