Compare commits
80 Commits
Author | SHA1 | Date | |
---|---|---|---|
a91dcb144d | |||
e7f7be2a2b | |||
076d89b5b5 | |||
8539930f89 | |||
87d9babbd3 | |||
9f2d3a1737 | |||
daf399163c | |||
cdf702e545 | |||
5811345050 | |||
53792a5cf7 | |||
8e10b7da37 | |||
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 | |||
6c1ae77a2a | |||
a56d976947 | |||
346b9b4b79 | |||
a5b8087dc5 | |||
7aa078e025 | |||
389fd158ad |
29
README.md
29
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.6-green.svg?style=for-the-badge">
|
||||
<img src="https://img.shields.io/badge/version-2.9.8-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
|
||||
@ -458,6 +457,32 @@ Special thanks to the following contributors:
|
||||
<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>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- markdownlint-enable -->
|
||||
|
@ -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, {
|
||||
|
@ -13,6 +13,8 @@ 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');
|
||||
|
||||
function omissions() {
|
||||
return ['is_deleted'];
|
||||
@ -335,6 +337,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
|
||||
@ -758,6 +825,7 @@ const internalCertificate = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Request a certificate using the http challenge
|
||||
* @param {Object} certificate the certificate row
|
||||
* @returns {Promise}
|
||||
*/
|
||||
@ -768,6 +836,7 @@ const internalCertificate = {
|
||||
'--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(',') + '" ' +
|
||||
|
48
backend/migrations/20200522113248_openid_connect.js
Normal file
48
backend/migrations/20200522113248_openid_connect.js
Normal file
@ -0,0 +1,48 @@
|
||||
const migrate_name = 'openid_connect';
|
||||
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('proxy_host', function (proxy_host) {
|
||||
proxy_host.integer('openidc_enabled').notNull().unsigned().defaultTo(0);
|
||||
proxy_host.text('openidc_redirect_uri').notNull().defaultTo('');
|
||||
proxy_host.text('openidc_discovery').notNull().defaultTo('');
|
||||
proxy_host.text('openidc_auth_method').notNull().defaultTo('');
|
||||
proxy_host.text('openidc_client_id').notNull().defaultTo('');
|
||||
proxy_host.text('openidc_client_secret').notNull().defaultTo('');
|
||||
})
|
||||
.then(() => {
|
||||
logger.info('[' + migrate_name + '] proxy_host Table altered');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Undo Migrate
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @param {Promise} Promise
|
||||
* @returns {Promise}
|
||||
*/
|
||||
exports.down = function (knex/*, Promise*/) {
|
||||
return knex.schema.table('proxy_host', function (proxy_host) {
|
||||
proxy_host.dropColumn('openidc_enabled');
|
||||
proxy_host.dropColumn('openidc_redirect_uri');
|
||||
proxy_host.dropColumn('openidc_discovery');
|
||||
proxy_host.dropColumn('openidc_auth_method');
|
||||
proxy_host.dropColumn('openidc_client_id');
|
||||
proxy_host.dropColumn('openidc_client_secret');
|
||||
})
|
||||
.then(() => {
|
||||
logger.info('[' + migrate_name + '] proxy_host Table altered');
|
||||
});
|
||||
};
|
40
backend/migrations/20200522144240_openid_allowed_users.js
Normal file
40
backend/migrations/20200522144240_openid_allowed_users.js
Normal file
@ -0,0 +1,40 @@
|
||||
const migrate_name = 'openid_allowed_users';
|
||||
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('proxy_host', function (proxy_host) {
|
||||
proxy_host.integer('openidc_restrict_users_enabled').notNull().unsigned().defaultTo(0);
|
||||
proxy_host.json('openidc_allowed_users').notNull().defaultTo([]);
|
||||
})
|
||||
.then(() => {
|
||||
logger.info('[' + migrate_name + '] proxy_host Table altered');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Undo Migrate
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @param {Promise} Promise
|
||||
* @returns {Promise}
|
||||
*/
|
||||
exports.down = function (knex/*, Promise*/) {
|
||||
return knex.schema.table('proxy_host', function (proxy_host) {
|
||||
proxy_host.dropColumn('openidc_restrict_users_enabled');
|
||||
proxy_host.dropColumn('openidc_allowed_users');
|
||||
})
|
||||
.then(() => {
|
||||
logger.info('[' + migrate_name + '] proxy_host Table altered');
|
||||
});
|
||||
};
|
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');
|
||||
});
|
||||
};
|
@ -20,12 +20,23 @@ class ProxyHost extends Model {
|
||||
this.domain_names = [];
|
||||
}
|
||||
|
||||
// Default for openidc_allowed_users
|
||||
if (typeof this.openidc_allowed_users === 'undefined') {
|
||||
this.openidc_allowed_users = [];
|
||||
}
|
||||
|
||||
// Default for meta
|
||||
if (typeof this.meta === 'undefined') {
|
||||
this.meta = {};
|
||||
}
|
||||
|
||||
// Openidc defaults
|
||||
if (typeof this.openidc_auth_method === 'undefined') {
|
||||
this.openidc_auth_method = 'client_secret_post';
|
||||
}
|
||||
|
||||
this.domain_names.sort();
|
||||
this.openidc_allowed_users.sort();
|
||||
}
|
||||
|
||||
$beforeUpdate () {
|
||||
@ -35,6 +46,11 @@ class ProxyHost extends Model {
|
||||
if (typeof this.domain_names !== 'undefined') {
|
||||
this.domain_names.sort();
|
||||
}
|
||||
|
||||
// Sort openidc_allowed_users
|
||||
if (typeof this.openidc_allowed_users !== 'undefined') {
|
||||
this.openidc_allowed_users.sort();
|
||||
}
|
||||
}
|
||||
|
||||
static get name () {
|
||||
@ -46,7 +62,7 @@ class ProxyHost extends Model {
|
||||
}
|
||||
|
||||
static get jsonAttributes () {
|
||||
return ['domain_names', 'meta', 'locations'];
|
||||
return ['domain_names', 'meta', 'locations', 'openidc_allowed_users'];
|
||||
}
|
||||
|
||||
static get relationMappings () {
|
||||
|
@ -5,6 +5,7 @@
|
||||
"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",
|
||||
|
@ -209,6 +209,35 @@ 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
|
||||
*
|
||||
|
@ -235,6 +235,43 @@
|
||||
"description": "Should we cache assets",
|
||||
"example": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
"openidc_enabled": {
|
||||
"description": "Is OpenID Connect authentication enabled",
|
||||
"example": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
"openidc_redirect_uri": {
|
||||
"type": "string"
|
||||
},
|
||||
"openidc_discovery": {
|
||||
"type": "string"
|
||||
},
|
||||
"openidc_auth_method": {
|
||||
"type": "string",
|
||||
"pattern": "^(client_secret_basic|client_secret_post)$"
|
||||
},
|
||||
"openidc_client_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"openidc_client_secret": {
|
||||
"type": "string"
|
||||
},
|
||||
"openidc_restrict_users_enabled": {
|
||||
"description": "Only allow a specific set of OpenID Connect emails to access the resource",
|
||||
"example": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
"openidc_allowed_users": {
|
||||
"type": "array",
|
||||
"minItems": 0,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"description": "Email Address",
|
||||
"example": "john@example.com",
|
||||
"format": "email",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,30 @@
|
||||
"advanced_config": {
|
||||
"type": "string"
|
||||
},
|
||||
"openidc_enabled": {
|
||||
"$ref": "../definitions.json#/definitions/openidc_enabled"
|
||||
},
|
||||
"openidc_redirect_uri": {
|
||||
"$ref": "../definitions.json#/definitions/openidc_redirect_uri"
|
||||
},
|
||||
"openidc_discovery": {
|
||||
"$ref": "../definitions.json#/definitions/openidc_discovery"
|
||||
},
|
||||
"openidc_auth_method": {
|
||||
"$ref": "../definitions.json#/definitions/openidc_auth_method"
|
||||
},
|
||||
"openidc_client_id": {
|
||||
"$ref": "../definitions.json#/definitions/openidc_client_id"
|
||||
},
|
||||
"openidc_client_secret": {
|
||||
"$ref": "../definitions.json#/definitions/openidc_client_secret"
|
||||
},
|
||||
"openidc_restrict_users_enabled": {
|
||||
"$ref": "../definitions.json#/definitions/openidc_restrict_users_enabled"
|
||||
},
|
||||
"openidc_allowed_users": {
|
||||
"$ref": "../definitions.json#/definitions/openidc_allowed_users"
|
||||
},
|
||||
"enabled": {
|
||||
"$ref": "../definitions.json#/definitions/enabled"
|
||||
},
|
||||
@ -161,6 +185,30 @@
|
||||
"advanced_config": {
|
||||
"$ref": "#/definitions/advanced_config"
|
||||
},
|
||||
"openidc_enabled": {
|
||||
"$ref": "#/definitions/openidc_enabled"
|
||||
},
|
||||
"openidc_redirect_uri": {
|
||||
"$ref": "#/definitions/openidc_redirect_uri"
|
||||
},
|
||||
"openidc_discovery": {
|
||||
"$ref": "#/definitions/openidc_discovery"
|
||||
},
|
||||
"openidc_auth_method": {
|
||||
"$ref": "#/definitions/openidc_auth_method"
|
||||
},
|
||||
"openidc_client_id": {
|
||||
"$ref": "#/definitions/openidc_client_id"
|
||||
},
|
||||
"openidc_client_secret": {
|
||||
"$ref": "#/definitions/openidc_client_secret"
|
||||
},
|
||||
"openidc_restrict_users_enabled": {
|
||||
"$ref": "#/definitions/openidc_restrict_users_enabled"
|
||||
},
|
||||
"openidc_allowed_users": {
|
||||
"$ref": "#/definitions/openidc_allowed_users"
|
||||
},
|
||||
"enabled": {
|
||||
"$ref": "#/definitions/enabled"
|
||||
},
|
||||
@ -251,6 +299,30 @@
|
||||
"advanced_config": {
|
||||
"$ref": "#/definitions/advanced_config"
|
||||
},
|
||||
"openidc_enabled": {
|
||||
"$ref": "#/definitions/openidc_enabled"
|
||||
},
|
||||
"openidc_redirect_uri": {
|
||||
"$ref": "#/definitions/openidc_redirect_uri"
|
||||
},
|
||||
"openidc_discovery": {
|
||||
"$ref": "#/definitions/openidc_discovery"
|
||||
},
|
||||
"openidc_auth_method": {
|
||||
"$ref": "#/definitions/openidc_auth_method"
|
||||
},
|
||||
"openidc_client_id": {
|
||||
"$ref": "#/definitions/openidc_client_id"
|
||||
},
|
||||
"openidc_client_secret": {
|
||||
"$ref": "#/definitions/openidc_client_secret"
|
||||
},
|
||||
"openidc_restrict_users_enabled": {
|
||||
"$ref": "#/definitions/openidc_restrict_users_enabled"
|
||||
},
|
||||
"openidc_allowed_users": {
|
||||
"$ref": "#/definitions/openidc_allowed_users"
|
||||
},
|
||||
"enabled": {
|
||||
"$ref": "#/definitions/enabled"
|
||||
},
|
||||
@ -324,6 +396,30 @@
|
||||
"advanced_config": {
|
||||
"$ref": "#/definitions/advanced_config"
|
||||
},
|
||||
"openidc_enabled": {
|
||||
"$ref": "#/definitions/openidc_enabled"
|
||||
},
|
||||
"openidc_redirect_uri": {
|
||||
"$ref": "#/definitions/openidc_redirect_uri"
|
||||
},
|
||||
"openidc_discovery": {
|
||||
"$ref": "#/definitions/openidc_discovery"
|
||||
},
|
||||
"openidc_auth_method": {
|
||||
"$ref": "#/definitions/openidc_auth_method"
|
||||
},
|
||||
"openidc_client_id": {
|
||||
"$ref": "#/definitions/openidc_client_id"
|
||||
},
|
||||
"openidc_client_secret": {
|
||||
"$ref": "#/definitions/openidc_client_secret"
|
||||
},
|
||||
"openidc_restrict_users_enabled": {
|
||||
"$ref": "#/definitions/openidc_restrict_users_enabled"
|
||||
},
|
||||
"openidc_allowed_users": {
|
||||
"$ref": "#/definitions/openidc_allowed_users"
|
||||
},
|
||||
"enabled": {
|
||||
"$ref": "#/definitions/enabled"
|
||||
},
|
||||
|
@ -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"
|
||||
|
@ -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 %}
|
||||
|
@ -1,10 +1,11 @@
|
||||
location {{ path }} {
|
||||
set $upstream {{ forward_scheme }}://{{ forward_host }}:{{ forward_port }}{{ forward_path }};
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Scheme $scheme;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_pass {{ forward_scheme }}://{{ forward_host }}:{{ forward_port }}{{ forward_path }};
|
||||
proxy_pass $upstream;
|
||||
|
||||
{% if access_list_id > 0 %}
|
||||
{% if access_list.items.length > 0 %}
|
||||
|
47
backend/templates/_openid_connect.conf
Normal file
47
backend/templates/_openid_connect.conf
Normal file
@ -0,0 +1,47 @@
|
||||
{% if openidc_enabled == 1 or openidc_enabled == true -%}
|
||||
access_by_lua_block {
|
||||
local openidc = require("resty.openidc")
|
||||
local opts = {
|
||||
redirect_uri = "{{- openidc_redirect_uri -}}",
|
||||
discovery = "{{- openidc_discovery -}}",
|
||||
token_endpoint_auth_method = "{{- openidc_auth_method -}}",
|
||||
client_id = "{{- openidc_client_id -}}",
|
||||
client_secret = "{{- openidc_client_secret -}}",
|
||||
scope = "openid email profile"
|
||||
}
|
||||
|
||||
local res, err = openidc.authenticate(opts)
|
||||
|
||||
if err then
|
||||
ngx.status = 500
|
||||
ngx.say(err)
|
||||
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
|
||||
end
|
||||
|
||||
{% if openidc_restrict_users_enabled == 1 or openidc_restrict_users_enabled == true -%}
|
||||
local function contains(table, val)
|
||||
for i=1,#table do
|
||||
if table[i] == val then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local allowed_users = {
|
||||
{% for user in openidc_allowed_users %}
|
||||
"{{ user }}",
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
if not contains(allowed_users, res.id_token.email) then
|
||||
ngx.exit(ngx.HTTP_FORBIDDEN)
|
||||
end
|
||||
{% endif -%}
|
||||
|
||||
|
||||
ngx.req.set_header("X-OIDC-SUB", res.id_token.sub)
|
||||
ngx.req.set_header("X-OIDC-EMAIL", res.id_token.email)
|
||||
ngx.req.set_header("X-OIDC-NAME", res.id_token.name)
|
||||
}
|
||||
{% endif %}
|
@ -16,6 +16,8 @@ server {
|
||||
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;
|
||||
|
@ -51,7 +51,8 @@ proxy_http_version 1.1;
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% include "_hsts.conf" %}
|
||||
{% include "_openid_connect.conf" %}
|
||||
{% include "_hsts.conf" %}
|
||||
|
||||
{% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %}
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
|
@ -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;
|
||||
|
@ -154,6 +154,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 +250,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 +265,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 +306,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,6 +381,11 @@ 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"
|
||||
@ -343,6 +396,14 @@ buffer-writer@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"
|
||||
resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.3.1.tgz#170899274c5bf38aae27d5c62b71268cd585fd1b"
|
||||
@ -457,7 +518,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 +623,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 +714,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"
|
||||
@ -831,7 +918,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 +1068,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 +1329,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 +1418,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 +1486,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"
|
||||
@ -1494,6 +1608,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 +1656,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 +2056,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 +2115,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 +2165,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"
|
||||
@ -2143,7 +2289,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 +2297,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 +2312,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==
|
||||
@ -2340,9 +2486,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"
|
||||
@ -2608,9 +2754,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"
|
||||
@ -2754,6 +2900,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"
|
||||
@ -2842,7 +2993,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 +3006,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"
|
||||
@ -3002,7 +3169,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==
|
||||
@ -3271,6 +3438,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"
|
||||
@ -3350,18 +3524,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"
|
||||
@ -3587,7 +3772,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=
|
||||
@ -3721,7 +3906,7 @@ y18n@^4.0.0:
|
||||
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==
|
||||
@ -3755,3 +3940,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
|
||||
@ -48,7 +48,6 @@ 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 \
|
||||
@ -26,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,4 +1,5 @@
|
||||
text = True
|
||||
non-interactive = True
|
||||
authenticator = webroot
|
||||
webroot-path = /data/letsencrypt-acme-challenge
|
||||
key-type = ecdsa
|
||||
elliptic-curve = secp384r1
|
||||
|
@ -9,9 +9,10 @@ server {
|
||||
|
||||
server_name localhost-nginx-proxy-manager;
|
||||
access_log /data/logs/fallback_access.log standard;
|
||||
error_log /dev/null crit;
|
||||
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;
|
||||
|
@ -43,6 +43,16 @@ http {
|
||||
proxy_cache_path /var/lib/nginx/cache/public levels=1:2 keys_zone=public-cache:30m max_size=192m;
|
||||
proxy_cache_path /var/lib/nginx/cache/private levels=1:2 keys_zone=private-cache:5m max_size=1024m;
|
||||
|
||||
lua_package_path '~/lua/?.lua;;';
|
||||
|
||||
lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
|
||||
lua_ssl_verify_depth 5;
|
||||
|
||||
# cache for discovery metadata documents
|
||||
lua_shared_dict discovery 1m;
|
||||
# cache for JWKs
|
||||
lua_shared_dict jwks 1m;
|
||||
|
||||
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"';
|
||||
|
||||
|
@ -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
|
||||
|
||||
@ -160,3 +172,26 @@ value by specifying it as a Docker environment variable. The default if not spec
|
||||
X_FRAME_OPTIONS: "sameorigin"
|
||||
...
|
||||
```
|
||||
|
||||
## OpenID Connect SSO
|
||||
|
||||
You can secure any of your proxy hosts with OpenID Connect authentication, providing SSO support from an identity provider like Azure AD or KeyCloak. OpenID Connect support is provided through the [`lua-resty-openidc`](https://github.com/zmartzone/lua-resty-openidc) library of [`OpenResty`](https://github.com/openresty/openresty).
|
||||
|
||||
You will need a few things to get started with OpenID Connect:
|
||||
|
||||
- A registered application with your identity provider, they will provide you with a `Client ID` and a `Client Secret`. Public OpenID Connect applications (without a client secret) are not yet supported.
|
||||
|
||||
- A redirect URL to send the users to after they login with the identity provider, this can be any unused URL under the proxy host, like `https://<proxy host url>/private/callback`, the server will take care of capturing that URL and redirecting you to the proxy host root. You will need to add this URL to the list of allowed redirect URLs for the application you registered with your identity provider.
|
||||
|
||||
- The well-known discovery endpoint of the identity provider you want to use, this is an URL usually with the form `https://<provider URL>/.well-known/openid-configuration`.
|
||||
|
||||
After you have all this you can proceed to configure the proxy host with OpenID Connect authentication.
|
||||
|
||||
You can also add some rudimentary access control through a list of allowed emails in case your identity provider doesn't let you do that, if this option is enabled, any email not on that list will be denied access to the proxied host.
|
||||
|
||||
The proxy adds some headers based on the authentication result from the identity provider:
|
||||
|
||||
- `X-OIDC-SUB`: The subject identifier, according to the OpenID Coonect spec: `A locally unique and never reassigned identifier within the Issuer for the End-User`.
|
||||
- `X-OIDC-EMAIL`: The email of the user that logged in, as specified in the `id_token` returned from the identity provider. The same value that will be checked for the email whitelist.
|
||||
- `X-OIDC-NAME`: The user's name claim from the `id_token`, please note that not all id tokens necessarily contain this claim.
|
||||
|
||||
|
@ -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==
|
||||
@ -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"
|
||||
@ -7173,9 +7173,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 +7699,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.24.0"
|
||||
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.24.0.tgz#0409c30068a6c52c89ef7f1089b3ca4de56be2ac"
|
||||
integrity sha512-SqV5GRsNqnzCL8k5dfAjCNhUrF3pR0A9lTDSCUZeh/LIshheXJEaP0hwLz2t4XHivd2J/v2HR+gRnigzeKe3cQ==
|
||||
|
||||
private@^0.1.8:
|
||||
version "0.1.8"
|
||||
@ -9156,14 +9154,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 +9650,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,14 @@ module.exports = {
|
||||
*/
|
||||
renew: function (id, timeout = 180000) {
|
||||
return fetch('post', 'nginx/certificates/' + id + '/renew', undefined, {timeout});
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Number} id
|
||||
* @returns {Promise}
|
||||
*/
|
||||
download: function (id) {
|
||||
return DownloadFile('get', "nginx/certificates/" + id + "/download", "certificate.zip")
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -41,6 +41,7 @@
|
||||
<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>
|
||||
<div class="dropdown-divider"></div>
|
||||
<% } %>
|
||||
<a href="#" class="delete dropdown-item"><i class="dropdown-icon fe fe-trash-2"></i> <%- i18n('str', 'delete') %></a>
|
||||
|
@ -11,7 +11,8 @@ module.exports = Mn.View.extend({
|
||||
ui: {
|
||||
host_link: '.host-link',
|
||||
renew: 'a.renew',
|
||||
delete: 'a.delete'
|
||||
delete: 'a.delete',
|
||||
download: 'a.download'
|
||||
},
|
||||
|
||||
events: {
|
||||
@ -29,6 +30,11 @@ 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'))
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
<li role="presentation" class="nav-item"><a href="#locations" aria-controls="tab4" role="tab" data-toggle="tab" class="nav-link"><i class="fe fe-layers"></i> <%- i18n('all-hosts', 'locations') %></a></li>
|
||||
<li role="presentation" class="nav-item"><a href="#ssl-options" aria-controls="tab2" role="tab" data-toggle="tab" class="nav-link"><i class="fe fe-shield"></i> <%- i18n('str', 'ssl') %></a></li>
|
||||
<li role="presentation" class="nav-item"><a href="#advanced" aria-controls="tab3" role="tab" data-toggle="tab" class="nav-link"><i class="fe fe-settings"></i> <%- i18n('all-hosts', 'advanced') %></a></li>
|
||||
<li role="presentation" class="nav-item"><a href="#openidc" aria-controls="tab3" role="tab" data-toggle="tab" class="nav-link"><i class="fe fe-settings"></i><%- i18n('proxy-hosts', 'oidc') %></a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
|
||||
@ -270,6 +271,71 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- OpenID Connect -->
|
||||
<div role="tabpanel" class="tab-pane" id="openidc">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-md-12">
|
||||
<div class="form-group">
|
||||
<label class="custom-switch">
|
||||
<input type="checkbox" class="custom-switch-input" name="openidc_enabled" value="1"<%- openidc_enabled ? ' checked' : '' %>>
|
||||
<span class="custom-switch-indicator"></span>
|
||||
<span class="custom-switch-description"><%- i18n('proxy-hosts', 'oidc-enabled') %></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12 openidc">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%- i18n('proxy-hosts', 'oidc-redirect-uri') %><span class="form-required">*</span></label>
|
||||
<input type="text" name="openidc_redirect_uri" class="form-control text-monospace" placeholder="" value="<%- openidc_redirect_uri %>" autocomplete="off" maxlength="255" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12 openidc">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%- i18n('proxy-hosts', 'oidc-discovery-endpoint') %><span class="form-required">*</span></label>
|
||||
<input type="text" name="openidc_discovery" class="form-control text-monospace" placeholder="" value="<%- openidc_discovery %>" autocomplete="off" maxlength="255" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12 openidc">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%- i18n('proxy-hosts', 'oidc-token-auth-method') %><span class="form-required">*</span></label>
|
||||
<select name="openidc_auth_method" class="form-control custom-select" placeholder="client_secret_post">
|
||||
<option value="client_secret_post" <%- openidc_auth_method === 'client_secret_post' ? 'selected' : '' %>>client_secret_post</option>
|
||||
<option value="client_secret_basic" <%- openidc_auth_method === 'client_secret_basic' ? 'selected' : '' %>>client_secret_basic</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12 openidc">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%- i18n('proxy-hosts', 'oidc-client-id') %><span class="form-required">*</span></label>
|
||||
<input type="text" name="openidc_client_id" class="form-control text-monospace" placeholder="" value="<%- openidc_client_id %>" autocomplete="off" maxlength="255" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12 openidc">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%- i18n('proxy-hosts', 'oidc-client-secret') %><span class="form-required">*</span></label>
|
||||
<input type="text" name="openidc_client_secret" class="form-control text-monospace" placeholder="" value="<%- openidc_client_secret %>" autocomplete="off" maxlength="255" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="openidc">
|
||||
<div class="col-sm-12 col-md-12">
|
||||
<div class="form-group">
|
||||
<label class="custom-switch">
|
||||
<input type="checkbox" class="custom-switch-input" name="openidc_restrict_users_enabled" value="1"<%- openidc_restrict_users_enabled ? ' checked' : '' %>>
|
||||
<span class="custom-switch-indicator"></span>
|
||||
<span class="custom-switch-description"><%- i18n('proxy-hosts', 'oidc-allow-only-emails') %></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12 openidc_users">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%- i18n('proxy-hosts', 'oidc-allowed-emails') %><span class="form-required">*</span></label>
|
||||
<input type="text" name="openidc_allowed_users" class="form-control" id="openidc_allowed_users" value="<%- openidc_allowed_users.join(',') %>" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -21,29 +21,34 @@ module.exports = Mn.View.extend({
|
||||
locationsCollection: new ProxyLocationModel.Collection(),
|
||||
|
||||
ui: {
|
||||
form: 'form',
|
||||
domain_names: 'input[name="domain_names"]',
|
||||
forward_host: 'input[name="forward_host"]',
|
||||
buttons: '.modal-footer button',
|
||||
cancel: 'button.cancel',
|
||||
save: 'button.save',
|
||||
add_location_btn: 'button.add_location',
|
||||
locations_container: '.locations_container',
|
||||
le_error_info: '#le-error-info',
|
||||
certificate_select: 'select[name="certificate_id"]',
|
||||
access_list_select: 'select[name="access_list_id"]',
|
||||
ssl_forced: 'input[name="ssl_forced"]',
|
||||
hsts_enabled: 'input[name="hsts_enabled"]',
|
||||
hsts_subdomains: 'input[name="hsts_subdomains"]',
|
||||
http2_support: 'input[name="http2_support"]',
|
||||
dns_challenge_switch: 'input[name="meta[dns_challenge]"]',
|
||||
dns_challenge_content: '.dns-challenge',
|
||||
dns_provider: 'select[name="meta[dns_provider]"]',
|
||||
credentials_file_content: '.credentials-file-content',
|
||||
dns_provider_credentials: 'textarea[name="meta[dns_provider_credentials]"]',
|
||||
propagation_seconds: 'input[name="meta[propagation_seconds]"]',
|
||||
forward_scheme: 'select[name="forward_scheme"]',
|
||||
letsencrypt: '.letsencrypt'
|
||||
form: 'form',
|
||||
domain_names: 'input[name="domain_names"]',
|
||||
forward_host: 'input[name="forward_host"]',
|
||||
buttons: '.modal-footer button',
|
||||
cancel: 'button.cancel',
|
||||
save: 'button.save',
|
||||
add_location_btn: 'button.add_location',
|
||||
locations_container: '.locations_container',
|
||||
le_error_info: '#le-error-info',
|
||||
certificate_select: 'select[name="certificate_id"]',
|
||||
access_list_select: 'select[name="access_list_id"]',
|
||||
ssl_forced: 'input[name="ssl_forced"]',
|
||||
hsts_enabled: 'input[name="hsts_enabled"]',
|
||||
hsts_subdomains: 'input[name="hsts_subdomains"]',
|
||||
http2_support: 'input[name="http2_support"]',
|
||||
dns_challenge_switch: 'input[name="meta[dns_challenge]"]',
|
||||
dns_challenge_content: '.dns-challenge',
|
||||
dns_provider: 'select[name="meta[dns_provider]"]',
|
||||
credentials_file_content: '.credentials-file-content',
|
||||
dns_provider_credentials: 'textarea[name="meta[dns_provider_credentials]"]',
|
||||
propagation_seconds: 'input[name="meta[propagation_seconds]"]',
|
||||
forward_scheme: 'select[name="forward_scheme"]',
|
||||
letsencrypt: '.letsencrypt',
|
||||
openidc_enabled: 'input[name="openidc_enabled"]',
|
||||
openidc_restrict_users_enabled: 'input[name="openidc_restrict_users_enabled"]',
|
||||
openidc_allowed_users: 'input[name="openidc_allowed_users"]',
|
||||
openidc: '.openidc',
|
||||
openidc_users: '.openidc_users',
|
||||
},
|
||||
|
||||
regions: {
|
||||
@ -113,7 +118,7 @@ module.exports = Mn.View.extend({
|
||||
} 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();
|
||||
}
|
||||
},
|
||||
|
||||
@ -125,13 +130,34 @@ module.exports = Mn.View.extend({
|
||||
this.ui.credentials_file_content.show();
|
||||
} else {
|
||||
this.ui.dns_provider_credentials.prop('required', false);
|
||||
this.ui.credentials_file_content.hide();
|
||||
this.ui.credentials_file_content.hide();
|
||||
}
|
||||
},
|
||||
|
||||
'change @ui.openidc_enabled': function () {
|
||||
let checked = this.ui.openidc_enabled.prop('checked');
|
||||
|
||||
if (checked) {
|
||||
this.ui.openidc.show().find('input').prop('disabled', false);
|
||||
} else {
|
||||
this.ui.openidc.hide().find('input').prop('disabled', true);
|
||||
}
|
||||
|
||||
this.ui.openidc_restrict_users_enabled.trigger('change');
|
||||
},
|
||||
|
||||
'change @ui.openidc_restrict_users_enabled': function () {
|
||||
let checked = this.ui.openidc_restrict_users_enabled.prop('checked');
|
||||
if (checked) {
|
||||
this.ui.openidc_users.show().find('input').prop('disabled', false);
|
||||
} else {
|
||||
this.ui.openidc_users.hide().find('input').prop('disabled', true);
|
||||
}
|
||||
},
|
||||
|
||||
'click @ui.add_location_btn': function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
|
||||
const model = new ProxyLocationModel.Model();
|
||||
this.locationsCollection.add(model);
|
||||
},
|
||||
@ -167,17 +193,25 @@ module.exports = Mn.View.extend({
|
||||
data.hsts_enabled = !!data.hsts_enabled;
|
||||
data.hsts_subdomains = !!data.hsts_subdomains;
|
||||
data.ssl_forced = !!data.ssl_forced;
|
||||
|
||||
data.openidc_enabled = data.openidc_enabled === '1';
|
||||
data.openidc_restrict_users_enabled = data.openidc_restrict_users_enabled === '1';
|
||||
|
||||
if (data.openidc_restrict_users_enabled) {
|
||||
if (typeof data.openidc_allowed_users === 'string' && data.openidc_allowed_users) {
|
||||
data.openidc_allowed_users = data.openidc_allowed_users.split(',');
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof data.meta === 'undefined') data.meta = {};
|
||||
data.meta.letsencrypt_agree = data.meta.letsencrypt_agree == 1;
|
||||
data.meta.dns_challenge = data.meta.dns_challenge == 1;
|
||||
|
||||
|
||||
if(!data.meta.dns_challenge){
|
||||
data.meta.dns_provider = undefined;
|
||||
data.meta.dns_provider_credentials = undefined;
|
||||
data.meta.propagation_seconds = undefined;
|
||||
} else {
|
||||
if(data.meta.propagation_seconds === '') data.meta.propagation_seconds = undefined;
|
||||
if(data.meta.propagation_seconds === '') data.meta.propagation_seconds = undefined;
|
||||
}
|
||||
|
||||
if (typeof data.domain_names === 'string' && data.domain_names) {
|
||||
@ -185,7 +219,7 @@ module.exports = Mn.View.extend({
|
||||
}
|
||||
|
||||
// Check for any domain names containing wildcards, which are not allowed with letsencrypt
|
||||
if (data.certificate_id === 'new') {
|
||||
if (data.certificate_id === 'new') {
|
||||
let domain_err = false;
|
||||
if (!data.meta.dns_challenge) {
|
||||
data.domain_names.map(function (name) {
|
||||
@ -203,6 +237,12 @@ module.exports = Mn.View.extend({
|
||||
data.certificate_id = parseInt(data.certificate_id, 10);
|
||||
}
|
||||
|
||||
// OpenID Connect won't work with multiple domain names because the redirect URL has to point to a specific one
|
||||
if (data.openidc_enabled && data.domain_names.length > 1) {
|
||||
alert('Cannot use mutliple domain names when OpenID Connect is enabled');
|
||||
return;
|
||||
}
|
||||
|
||||
let method = App.Api.Nginx.ProxyHosts.create;
|
||||
let is_new = true;
|
||||
|
||||
@ -344,6 +384,23 @@ module.exports = Mn.View.extend({
|
||||
view.ui.certificate_select[0].selectize.setValue(view.model.get('certificate_id'));
|
||||
}
|
||||
});
|
||||
|
||||
// OpenID Connect
|
||||
this.ui.openidc_allowed_users.selectize({
|
||||
delimiter: ',',
|
||||
persist: false,
|
||||
maxOptions: 15,
|
||||
create: function (input) {
|
||||
return {
|
||||
value: input,
|
||||
text: input
|
||||
};
|
||||
}
|
||||
});
|
||||
this.ui.openidc.hide().find('input').prop('disabled', true);
|
||||
this.ui.openidc_users.hide().find('input').prop('disabled', true);
|
||||
this.ui.openidc_enabled.trigger('change');
|
||||
this.ui.openidc_restrict_users_enabled.trigger('change');
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
|
@ -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>
|
||||
|
@ -130,7 +130,16 @@
|
||||
"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": "Use 1.1.1.1/path for sub-folder forwarding",
|
||||
"oidc": "OpenID Connect",
|
||||
"oidc-enabled": "Use OpenID Connect authentication",
|
||||
"oidc-redirect-uri": "Redirect URI",
|
||||
"oidc-discovery-endpoint": "Well-known discovery endpoint",
|
||||
"oidc-token-auth-method": "Token endpoint auth method",
|
||||
"oidc-client-id": "Client ID",
|
||||
"oidc-client-secret": "Client secret",
|
||||
"oidc-allow-only-emails": "Allow only these user emails",
|
||||
"oidc-allowed-emails": "Allowed email addresses"
|
||||
},
|
||||
"redirection-hosts": {
|
||||
"title": "Redirection Hosts",
|
||||
@ -162,7 +171,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 +197,7 @@
|
||||
"other-certificate-key": "Certificate Key",
|
||||
"other-intermediate-certificate": "Intermediate Certificate",
|
||||
"force-renew": "Renew Now",
|
||||
"download": "Download",
|
||||
"renew-title": "Renew Let'sEncrypt Certificate"
|
||||
},
|
||||
"access-lists": {
|
||||
|
@ -22,6 +22,14 @@ const model = Backbone.Model.extend({
|
||||
block_exploits: false,
|
||||
http2_support: false,
|
||||
advanced_config: '',
|
||||
openidc_enabled: false,
|
||||
openidc_redirect_uri: '',
|
||||
openidc_discovery: '',
|
||||
openidc_auth_method: 'client_secret_post',
|
||||
openidc_client_id: '',
|
||||
openidc_client_secret: '',
|
||||
openidc_restrict_users_enabled: false,
|
||||
openidc_allowed_users: [],
|
||||
enabled: true,
|
||||
meta: {},
|
||||
// The following are expansions:
|
||||
|
@ -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,
|
||||
|
@ -5112,9 +5112,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-type@^1.0.0:
|
||||
version "1.1.0"
|
||||
|
@ -314,6 +314,16 @@ dns_linode_version = [<blank>|3|4]`,
|
||||
full_plugin_name: 'dns-linode',
|
||||
},
|
||||
//####################################################//
|
||||
loopia: {
|
||||
display_name: 'Loopia',
|
||||
package_name: 'certbot-dns-loopia',
|
||||
package_version: '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',
|
||||
@ -442,4 +452,14 @@ certbot_dns_transip:dns_transip_key_file = /etc/letsencrypt/transip-rsa.key`,
|
||||
credentials: 'certbot_dns_vultr:dns_vultr_key = YOUR_VULTR_API_KEY',
|
||||
full_plugin_name: 'certbot-dns-vultr:dns-vultr',
|
||||
},
|
||||
//####################################################//
|
||||
desec: {
|
||||
display_name: 'deSEC',
|
||||
package_name: 'certbot-dns-desec',
|
||||
package_version: '0.3.0',
|
||||
dependencies: '',
|
||||
credentials: `certbot_dns_desec:dns_desec_token = YOUR_DESEC_API_TOKEN
|
||||
certbot_dns_desec:dns_desec_endpoint = https://desec.io/api/v1/`,
|
||||
full_plugin_name: 'certbot-dns-desec:dns-desec',
|
||||
},
|
||||
};
|
||||
|
Reference in New Issue
Block a user