Compare commits

...

13 Commits

18 changed files with 78 additions and 63 deletions

View File

@ -1 +1 @@
2.12.4
2.12.5

15
Jenkinsfile vendored
View File

@ -241,12 +241,17 @@ pipeline {
}
steps {
script {
npmGithubPrComment("""Docker Image for build ${BUILD_NUMBER} is available on
[DockerHub](https://cloud.docker.com/repository/docker/nginxproxymanager/${IMAGE}-dev)
as `nginxproxymanager/${IMAGE}-dev:${BRANCH_LOWER}`
npmGithubPrComment("""Docker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker/nginxproxymanager/${IMAGE}-dev):
```
nginxproxymanager/${IMAGE}-dev:${BRANCH_LOWER}
```
**Note:** ensure you backup your NPM instance before testing this image! Especially if there are database changes
**Note:** this is a different docker image namespace than the official image
> [!NOTE]
> Ensure you backup your NPM instance before testing this image! Especially if there are database changes.
> This is a different docker image namespace than the official image.
> [!WARNING]
> Changes and additions to DNS Providers require verification by at least 2 members of the community!
""", true)
}
}

View File

@ -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.12.4-green.svg?style=for-the-badge">
<img src="https://img.shields.io/badge/version-2.12.5-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>

View File

@ -11,7 +11,7 @@ const certbot = {
/**
* @param {array} pluginKeys
*/
installPlugins: async function (pluginKeys) {
installPlugins: async (pluginKeys) => {
let hasErrors = false;
return new Promise((resolve, reject) => {
@ -21,7 +21,7 @@ const certbot = {
}
batchflow(pluginKeys).sequential()
.each((i, pluginKey, next) => {
.each((_i, pluginKey, next) => {
certbot.installPlugin(pluginKey)
.then(() => {
next();
@ -51,7 +51,7 @@ const certbot = {
* @param {string} pluginKey
* @returns {Object}
*/
installPlugin: async function (pluginKey) {
installPlugin: async (pluginKey) => {
if (typeof dnsPlugins[pluginKey] === 'undefined') {
// throw Error(`Certbot plugin ${pluginKey} not found`);
throw new error.ItemNotFoundError(pluginKey);
@ -63,8 +63,15 @@ const certbot = {
plugin.version = plugin.version.replace(/{{certbot-version}}/g, CERTBOT_VERSION_REPLACEMENT);
plugin.dependencies = plugin.dependencies.replace(/{{certbot-version}}/g, CERTBOT_VERSION_REPLACEMENT);
const cmd = '. /opt/certbot/bin/activate && pip install --no-cache-dir ' + plugin.dependencies + ' ' + plugin.package_name + plugin.version + ' ' + ' && deactivate';
return utils.exec(cmd)
// SETUPTOOLS_USE_DISTUTILS is required for certbot plugins to install correctly
// in new versions of Python
let env = Object.assign({}, process.env, {SETUPTOOLS_USE_DISTUTILS: 'stdlib'});
if (typeof plugin.env === 'object') {
env = Object.assign(env, plugin.env);
}
const cmd = `. /opt/certbot/bin/activate && pip install --no-cache-dir ${plugin.dependencies} ${plugin.package_name}${plugin.version} && deactivate`;
return utils.exec(cmd, {env})
.then((result) => {
logger.complete(`Installed ${pluginKey}`);
return result;

View File

@ -1,13 +1,13 @@
const _ = require('lodash');
const exec = require('child_process').exec;
const execFile = require('child_process').execFile;
const exec = require('node:child_process').exec;
const execFile = require('node:child_process').execFile;
const { Liquid } = require('liquidjs');
const logger = require('../logger').global;
const error = require('./error');
module.exports = {
exec: async function(cmd, options = {}) {
exec: async (cmd, options = {}) => {
logger.debug('CMD:', cmd);
const { stdout, stderr } = await new Promise((resolve, reject) => {
@ -31,11 +31,11 @@ module.exports = {
* @param {Array} args
* @returns {Promise}
*/
execFile: function (cmd, args) {
execFile: (cmd, args) => {
// logger.debug('CMD: ' + cmd + ' ' + (args ? args.join(' ') : ''));
return new Promise((resolve, reject) => {
execFile(cmd, args, function (err, stdout, /*stderr*/) {
execFile(cmd, args, (err, stdout, /*stderr*/) => {
if (err && typeof err === 'object') {
reject(err);
} else {
@ -51,7 +51,7 @@ module.exports = {
* @param {Array} omissions
* @returns {Function}
*/
omitRow: function (omissions) {
omitRow: (omissions) => {
/**
* @param {Object} row
* @returns {Object}
@ -67,7 +67,7 @@ module.exports = {
* @param {Array} omissions
* @returns {Function}
*/
omitRows: function (omissions) {
omitRows: (omissions) => {
/**
* @param {Array} rows
* @returns {Object}
@ -83,9 +83,9 @@ module.exports = {
/**
* @returns {Object} Liquid render engine
*/
getRenderEngine: function () {
getRenderEngine: () => {
const renderEngine = new Liquid({
root: __dirname + '/../templates/'
root: `${__dirname}/../templates/`
});
/**

View File

@ -28,7 +28,10 @@ CERT_INIT_FLAG="/opt/certbot/.ownership_initialized"
if [ ! -f "$CERT_INIT_FLAG" ]; then
# Prevents errors when installing python certbot plugins when non-root
chown "$PUID:$PGID" /opt/certbot /opt/certbot/bin
if [ "$SKIP_CERTBOT_OWNERSHIP" != "true" ]; then
log_info 'Changing ownership of /opt/certbot directories ...'
chown "$PUID:$PGID" /opt/certbot /opt/certbot/bin
fi
# Handle all site-packages directories efficiently
find /opt/certbot/lib -type d -name "site-packages" | while read -r SITE_PACKAGES_DIR; do

View File

@ -8,7 +8,7 @@ BLUE='\E[1;34m'
GREEN='\E[1;32m'
RESET='\E[0m'
S6_OVERLAY_VERSION=3.2.0.2
S6_OVERLAY_VERSION=3.2.1.0
TARGETPLATFORM=${1:-linux/amd64}
# Determine the correct binary file for the architecture given

View File

@ -56,18 +56,18 @@
"full_plugin_name": "dns-bunny"
},
"cdmon": {
"name": "cdmon",
"package_name": "certbot-dns-cdmon",
"version": "~=0.4.1",
"dependencies": "",
"credentials": "dns_cdmon_api_key=your-cdmon-api-token\ndns_cdmon_domain=your_domain_is_optional",
"full_plugin_name": "dns-cdmon"
},
"name": "cdmon",
"package_name": "certbot-dns-cdmon",
"version": "~=0.4.1",
"dependencies": "",
"credentials": "dns_cdmon_api_key=your-cdmon-api-token\ndns_cdmon_domain=your_domain_is_optional",
"full_plugin_name": "dns-cdmon"
},
"cloudflare": {
"name": "Cloudflare",
"package_name": "certbot-dns-cloudflare",
"version": "=={{certbot-version}}",
"dependencies": "cloudflare==4.0.* acme=={{certbot-version}}",
"dependencies": "acme=={{certbot-version}}",
"credentials": "# Cloudflare API token\ndns_cloudflare_api_token=0123456789abcdef0123456789abcdef01234567",
"full_plugin_name": "dns-cloudflare"
},

View File

@ -10,7 +10,7 @@ describe('Certificates endpoints', () => {
});
});
it('Validate custom certificate', function() {
it('Validate custom certificate', () => {
cy.task('backendApiPostFiles', {
token: token,
path: '/api/nginx/certificates/validate',
@ -25,7 +25,7 @@ describe('Certificates endpoints', () => {
});
});
it('Custom certificate lifecycle', function() {
it('Custom certificate lifecycle', () => {
// Create custom cert
cy.task('backendApiPost', {
token: token,
@ -73,7 +73,7 @@ describe('Certificates endpoints', () => {
});
});
it('Request Certificate - CVE-2024-46256/CVE-2024-46257', function() {
it('Request Certificate - CVE-2024-46256/CVE-2024-46257', () => {
cy.task('backendApiPost', {
token: token,
path: '/api/nginx/certificates',

View File

@ -9,7 +9,7 @@ describe('Dashboard endpoints', () => {
});
});
it('Should be able to get host counts', function() {
it('Should be able to get host counts', () => {
cy.task('backendApiGet', {
token: token,
path: '/api/reports/hosts'

View File

@ -9,7 +9,7 @@ describe('Full Certificate Provisions', () => {
});
});
it('Should be able to create new http certificate', function() {
it('Should be able to create new http certificate', () => {
cy.task('backendApiPost', {
token: token,
path: '/api/nginx/certificates',
@ -32,7 +32,7 @@ describe('Full Certificate Provisions', () => {
});
});
it('Should be able to create new DNS certificate with Powerdns', function() {
it('Should be able to create new DNS certificate with Powerdns', () => {
cy.task('backendApiPost', {
token: token,
path: '/api/nginx/certificates',

View File

@ -1,7 +1,7 @@
/// <reference types="cypress" />
describe('Basic API checks', () => {
it('Should return a valid health payload', function () {
it('Should return a valid health payload', () => {
cy.task('backendApiGet', {
path: '/api/',
}).then((data) => {
@ -10,9 +10,9 @@ describe('Basic API checks', () => {
});
});
it('Should return a valid schema payload', function () {
it('Should return a valid schema payload', () => {
cy.task('backendApiGet', {
path: '/api/schema?ts=' + Date.now(),
path: `/api/schema?ts=${Date.now()}`,
}).then((data) => {
expect(data.openapi).to.be.equal('3.1.0');
});

View File

@ -1,12 +1,12 @@
/// <reference types="cypress" />
describe('LDAP with Authentik', () => {
let token;
let _token;
if (Cypress.env('skipStackCheck') === 'true' || Cypress.env('stack') === 'postgres') {
before(() => {
cy.getToken().then((tok) => {
token = tok;
_token = tok;
// cy.task('backendApiPut', {
// token: token,
@ -45,7 +45,7 @@ describe('LDAP with Authentik', () => {
});
});
it.skip('Should log in with LDAP', function() {
it.skip('Should log in with LDAP', () => {
// cy.task('backendApiPost', {
// token: token,
// path: '/api/auth',

View File

@ -1,12 +1,12 @@
/// <reference types="cypress" />
describe('OAuth with Authentik', () => {
let token;
let _token;
if (Cypress.env('skipStackCheck') === 'true' || Cypress.env('stack') === 'postgres') {
before(() => {
cy.getToken().then((tok) => {
token = tok;
_token = tok;
// cy.task('backendApiPut', {
// token: token,
@ -47,7 +47,7 @@ describe('OAuth with Authentik', () => {
});
});
it.skip('Should log in with OAuth', function() {
it.skip('Should log in with OAuth', () => {
// cy.task('backendApiGet', {
// path: '/oauth/login?redirect_base=' + encodeURI(Cypress.config('baseUrl')),
// }).then((data) => {

View File

@ -9,7 +9,7 @@ describe('Proxy Hosts endpoints', () => {
});
});
it('Should be able to create a http host', function() {
it('Should be able to create a http host', () => {
cy.task('backendApiPost', {
token: token,
path: '/api/nginx/proxy-hosts',

View File

@ -9,7 +9,7 @@ describe('Settings endpoints', () => {
});
});
it('Get all settings', function() {
it('Get all settings', () => {
cy.task('backendApiGet', {
token: token,
path: '/api/settings',
@ -19,7 +19,7 @@ describe('Settings endpoints', () => {
});
});
it('Get default-site setting', function() {
it('Get default-site setting', () => {
cy.task('backendApiGet', {
token: token,
path: '/api/settings/default-site',
@ -30,7 +30,7 @@ describe('Settings endpoints', () => {
});
});
it('Default Site congratulations', function() {
it('Default Site congratulations', () => {
cy.task('backendApiPut', {
token: token,
path: '/api/settings/default-site',
@ -46,7 +46,7 @@ describe('Settings endpoints', () => {
});
});
it('Default Site 404', function() {
it('Default Site 404', () => {
cy.task('backendApiPut', {
token: token,
path: '/api/settings/default-site',
@ -62,7 +62,7 @@ describe('Settings endpoints', () => {
});
});
it('Default Site 444', function() {
it('Default Site 444', () => {
cy.task('backendApiPut', {
token: token,
path: '/api/settings/default-site',
@ -78,7 +78,7 @@ describe('Settings endpoints', () => {
});
});
it('Default Site redirect', function() {
it('Default Site redirect', () => {
cy.task('backendApiPut', {
token: token,
path: '/api/settings/default-site',
@ -100,7 +100,7 @@ describe('Settings endpoints', () => {
});
});
it('Default Site html', function() {
it('Default Site html', () => {
cy.task('backendApiPut', {
token: token,
path: '/api/settings/default-site',

View File

@ -33,7 +33,7 @@ describe('Streams', () => {
cy.exec('rm -f /test/results/testssl.json');
});
it('Should be able to create TCP Stream', function() {
it('Should be able to create TCP Stream', () => {
cy.task('backendApiPost', {
token: token,
path: '/api/nginx/streams',
@ -65,7 +65,7 @@ describe('Streams', () => {
});
});
it('Should be able to create UDP Stream', function() {
it('Should be able to create UDP Stream', () => {
cy.task('backendApiPost', {
token: token,
path: '/api/nginx/streams',
@ -92,7 +92,7 @@ describe('Streams', () => {
});
});
it('Should be able to create TCP/UDP Stream', function() {
it('Should be able to create TCP/UDP Stream', () => {
cy.task('backendApiPost', {
token: token,
path: '/api/nginx/streams',
@ -124,7 +124,7 @@ describe('Streams', () => {
});
});
it('Should be able to create SSL TCP Stream', function() {
it('Should be able to create SSL TCP Stream', () => {
let certID = 0;
// Create custom cert
@ -184,7 +184,7 @@ describe('Streams', () => {
cy.exec('/testssl/testssl.sh --quiet --add-ca="$(/bin/mkcert -CAROOT)/rootCA.pem" --jsonfile=/test/results/testssl.json website1.example.com:1503', {
timeout: 120000, // 2 minutes
}).then((result) => {
cy.task('log', '[testssl.sh] ' + result.stdout);
cy.task('log', `[testssl.sh] ${result.stdout}`);
const allowedSeverities = ["INFO", "OK", "LOW", "MEDIUM"];
const ignoredIDs = [
@ -210,7 +210,7 @@ describe('Streams', () => {
});
});
it('Should be able to List Streams', function() {
it('Should be able to List Streams', () => {
cy.task('backendApiGet', {
token: token,
path: '/api/nginx/streams?expand=owner,certificate',

View File

@ -9,7 +9,7 @@ describe('Users endpoints', () => {
});
});
it('Should be able to get yourself', function() {
it('Should be able to get yourself', () => {
cy.task('backendApiGet', {
token: token,
path: '/api/users/me'
@ -20,7 +20,7 @@ describe('Users endpoints', () => {
});
});
it('Should be able to get all users', function() {
it('Should be able to get all users', () => {
cy.task('backendApiGet', {
token: token,
path: '/api/users'
@ -30,7 +30,7 @@ describe('Users endpoints', () => {
});
});
it('Should be able to update yourself', function() {
it('Should be able to update yourself', () => {
cy.task('backendApiPut', {
token: token,
path: '/api/users/me',