Compare commits

...

25 Commits

Author SHA1 Message Date
07a4e5791f Merge pull request #4179 from tametsi/develop
All checks were successful
Close stale issues and PRs / stale (push) Successful in 4s
Return generic auth error to prevent user enumeration attacks
2024-11-23 22:39:37 +10:00
640a1eeb68 Return generic auth error to prevent user enumeration attacks
On invalid user/password error the error message "Invalid email or password" is returned.
Thereby, no information about the existence of the user is given.
2024-11-22 10:37:09 +01:00
25a26d6175 Merge pull request #4112 from prospo/develop
All checks were successful
Close stale issues and PRs / stale (push) Successful in 4s
feat: Add leaseweb to certbot-dns-plugins
2024-10-30 14:40:20 +10:00
17246e418f Merge pull request #4118 from mitossoft-rd/patch-1
Remove variable usage from proxy_pass directive to fix resolution issues
2024-10-30 14:39:48 +10:00
f7d3ca0b07 Cleaning unused variable. 2024-10-28 15:18:54 +03:00
a55de386e7 Fix URL format 2024-10-28 15:15:08 +03:00
e9d4f5b827 Remove variable usage from proxy_pass directive to fix resolution issues
By using a static URL, the backend server can be accessed reliably, avoiding the common 404 errors or "no resolver defined" issues seen when variables are used.
2024-10-28 02:59:23 +03:00
1c1cee3836 feat: Add leaseweb to certbot-dns-plugins 2024-10-25 13:25:09 +00:00
eaf6335694 Merge pull request #4106 from dreik/develop
All checks were successful
Close stale issues and PRs / stale (push) Successful in 4s
http2 directive migration
2024-10-25 08:53:08 +10:00
ffe05ebd41 Merge pull request #4108 from chrismaffey/patch-2
Update put.json
2024-10-25 08:06:50 +10:00
2e9a4f1aed Update put.json
Password can be left blank for updates.  Otherwise you have to reenter the password every time you save the auth list
2024-10-24 17:29:16 +13:00
d17c85e4c8 Merge pull request #4107 from chrismaffey/patch-1
Update _access.conf
2024-10-24 11:31:12 +10:00
dad8d0ca00 Update _access.conf
the pass_auth and satisfy_any properties and now boolean true/false, they do not == 1 so the switching in this template breaks
2024-10-24 14:04:17 +13:00
d7e0558a35 http2 directive
to reduce warns in logs
2024-10-24 01:30:14 +03:00
ee41bb5562 Merge pull request #4078 from Guiorgy/patch-1
All checks were successful
Close stale issues and PRs / stale (push) Successful in 4s
normalize indentations in certbot-dns-plugins.json
2024-10-22 10:14:31 +10:00
0cf6b9caa4 Merge pull request #4084 from ttodua/patch-1
doc(site) - default credentials change
2024-10-22 10:14:11 +10:00
68a9baf206 minor 2024-10-18 15:35:15 +04:00
d92421d098 doc(site) - default credentials change 2024-10-18 15:33:32 +04:00
96c58b203e normalize indentations in certbot-dns-plugins.json 2024-10-17 15:34:04 +04:00
d499e2bfef Push PR and github branch builds to separate docker image
All checks were successful
Close stale issues and PRs / stale (push) Successful in 4s
2024-10-17 10:00:12 +10:00
2f9e062718 bump version 2024-10-17 09:05:25 +10:00
edbed1af90 Adds tests for settings endpoints
and reenables dns cert test
and fixes problems with schema
2024-10-17 08:48:47 +10:00
8497022e41 Merge pull request #4076 from Nephiel/4074-fix-1
All checks were successful
Close stale issues and PRs / stale (push) Successful in 5s
Fix schema validation errors
2024-10-17 07:07:05 +10:00
fa2c814fcb Fix schema validation in Default Site
Should solve error `data/value must match exactly one schema in oneOf` when setting the Default Site to 404 or 444. #4074
2024-10-16 19:09:14 +00:00
d96a3987c0 Fix forward_scheme validation in Redirection Host
Should solve error `data/forward_scheme must be equal to one of the allowed values` when configuring a Redirection Host with scheme set to `auto`. #4074
2024-10-16 19:04:50 +00:00
26 changed files with 213 additions and 69 deletions

View File

@ -1 +1 @@
2.12.0
2.12.1

10
Jenkinsfile vendored
View File

@ -43,7 +43,7 @@ pipeline {
steps {
script {
// Defaults to the Branch name, which is applies to all branches AND pr's
buildxPushTags = "-t docker.io/jc21/${IMAGE}:github-${BRANCH_LOWER}"
buildxPushTags = "-t docker.io/nginxproxymanager/${IMAGE}-dev:${BRANCH_LOWER}"
}
}
}
@ -203,7 +203,13 @@ pipeline {
}
steps {
script {
npmGithubPrComment("Docker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker/jc21/${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`\n\n**Note:** ensure you backup your NPM instance before testing this PR image! Especially if this PR contains database changes.", true)
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}`
**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
""", 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.0-green.svg?style=for-the-badge">
<img src="https://img.shields.io/badge/version-2.12.1-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

@ -181,7 +181,9 @@ const internalNginx = {
* @param {Object} host
* @returns {Promise}
*/
generateConfig: (host_type, host) => {
generateConfig: (host_type, host_row) => {
// Prevent modifying the original object:
let host = JSON.parse(JSON.stringify(host_row));
const nice_host_type = internalNginx.getFileFriendlyHostType(host_type);
if (config.debug()) {

View File

@ -5,6 +5,8 @@ const authModel = require('../models/auth');
const helpers = require('../lib/helpers');
const TokenModel = require('../models/token');
const ERROR_MESSAGE_INVALID_AUTH = 'Invalid email or password';
module.exports = {
/**
@ -69,15 +71,15 @@ module.exports = {
};
});
} else {
throw new error.AuthError('Invalid password');
throw new error.AuthError(ERROR_MESSAGE_INVALID_AUTH);
}
});
} else {
throw new error.AuthError('No password auth for user');
throw new error.AuthError(ERROR_MESSAGE_INVALID_AUTH);
}
});
} else {
throw new error.AuthError('No relevant user found');
throw new error.AuthError(ERROR_MESSAGE_INVALID_AUTH);
}
});
},

View File

@ -23,9 +23,7 @@
"locations",
"hsts_enabled",
"hsts_subdomains",
"certificate",
"use_default_location",
"ipv6"
"certificate"
],
"additionalProperties": false,
"properties": {
@ -151,12 +149,6 @@
"$ref": "./access-list-object.json"
}
]
},
"use_default_location": {
"type": "boolean"
},
"ipv6": {
"type": "boolean"
}
}
}

View File

@ -28,7 +28,7 @@
},
"forward_scheme": {
"type": "string",
"enum": ["http", "https"]
"enum": ["auto", "http", "https"]
},
"forward_domain_name": {
"description": "Domain Name",

View File

@ -25,7 +25,7 @@
"value": {
"description": "Value in almost any form",
"example": "congratulations",
"oneOf": [
"anyOf": [
{
"type": "string",
"minLength": 1
@ -46,7 +46,10 @@
},
"meta": {
"description": "Extra metadata",
"example": {},
"example": {
"redirect": "http://example.com",
"html": "<h1>404</h1>"
},
"type": "object"
}
}

View File

@ -49,8 +49,7 @@
"minLength": 1
},
"password": {
"type": "string",
"minLength": 1
"type": "string"
}
}
}

View File

@ -94,9 +94,7 @@
"avatar": "",
"roles": ["admin"]
},
"certificate": null,
"use_default_location": true,
"ipv6": true
"certificate": null
}
}
},

View File

@ -79,9 +79,7 @@
"nickname": "Admin",
"avatar": "",
"roles": ["admin"]
},
"use_default_location": true,
"ipv6": true
}
}
}
},

View File

@ -129,9 +129,7 @@
"roles": ["admin"]
},
"certificate": null,
"access_list": null,
"use_default_location": true,
"ipv6": true
"access_list": null
}
}
},

View File

@ -114,9 +114,7 @@
"avatar": "//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?default=mm",
"roles": ["admin"]
},
"access_list": null,
"use_default_location": true,
"ipv6": true
"access_list": null
}
}
},

View File

@ -114,9 +114,7 @@
"avatar": "",
"roles": ["admin"]
},
"certificate": null,
"use_default_location": true,
"ipv6": true
"certificate": null
}
}
},

View File

@ -99,9 +99,7 @@
"nickname": "Admin",
"avatar": "",
"roles": ["admin"]
},
"use_default_location": true,
"ipv6": true
}
}
}
},

View File

@ -129,9 +129,7 @@
"roles": ["admin"]
},
"certificate": null,
"access_list": null,
"use_default_location": true,
"ipv6": true
"access_list": null
}
}
},

View File

@ -13,7 +13,8 @@
"name": "settingID",
"schema": {
"type": "string",
"minLength": 1
"minLength": 1,
"enum": ["default-site"]
},
"required": true,
"description": "Setting ID",
@ -31,10 +32,21 @@
"minProperties": 1,
"properties": {
"value": {
"$ref": "../../../components/setting-object.json#/properties/value"
"type": "string",
"minLength": 1,
"enum": ["congratulations", "404", "444", "redirect", "html"]
},
"meta": {
"$ref": "../../../components/setting-object.json#/properties/meta"
"type": "object",
"additionalProperties": false,
"properties": {
"redirect": {
"type": "string"
},
"html": {
"type": "string"
}
}
}
}
}

View File

@ -4,7 +4,7 @@
auth_basic "Authorization required";
auth_basic_user_file /data/access/{{ access_list_id }};
{% if access_list.pass_auth == 0 %}
{% if access_list.pass_auth == 0 or access_list.pass_auth == true %}
proxy_set_header Authorization "";
{% endif %}
@ -17,7 +17,7 @@
deny all;
# Access checks must...
{% if access_list.satisfy_any == 1 %}
{% if access_list.satisfy_any == 1 or access_list.satisfy_any == true %}
satisfy any;
{% else %}
satisfy all;

View File

@ -5,11 +5,16 @@
#listen [::]:80;
{% endif %}
{% if certificate -%}
listen 443 ssl{% if http2_support == 1 or http2_support == true %} http2{% endif %};
listen 443 ssl;
{% if ipv6 -%}
listen [::]:443 ssl{% if http2_support == 1 or http2_support == true %} http2{% endif %};
listen [::]:443 ssl;
{% else -%}
#listen [::]:443;
{% endif %}
{% endif %}
server_name {{ domain_names | join: " " }};
{% if http2_support == 1 or http2_support == true %}
http2 on;
{% else -%}
http2 off;
{% endif %}

View File

@ -7,11 +7,7 @@
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
set $proxy_forward_scheme {{ forward_scheme }};
set $proxy_server "{{ forward_host }}";
set $proxy_port {{ forward_port }};
proxy_pass $proxy_forward_scheme://$proxy_server:$proxy_port{{ forward_path }};
proxy_pass {{ forward_scheme }}://{{ forward_host }}:{{ forward_port }}{{ forward_path }};
{% include "_access.conf" %}
{% include "_assets.conf" %}

View File

@ -137,5 +137,13 @@ Email: admin@example.com
Password: changeme
```
Immediately after logging in with this default user you will be asked to modify your details and change your password.
Immediately after logging in with this default user you will be asked to modify your details and change your password. You can change defaults with:
```
environment:
INITIAL_ADMIN_EMAIL: my@example.com
INITIAL_ADMIN_PASSWORD: mypassword1
```

View File

@ -7,7 +7,7 @@
"credentials": "dns_acmedns_api_url = http://acmedns-server/\ndns_acmedns_registration_file = /data/acme-registration.json",
"full_plugin_name": "dns-acmedns"
},
"active24":{
"active24":{
"name": "Active24",
"package_name": "certbot-dns-active24",
"version": "~=1.5.1",
@ -303,6 +303,14 @@
"credentials": "dns_joker_username = <Dynamic DNS Authentication Username>\ndns_joker_password = <Dynamic DNS Authentication Password>\ndns_joker_domain = <Dynamic DNS Domain>",
"full_plugin_name": "dns-joker"
},
"leaseweb": {
"name": "LeaseWeb",
"package_name": "certbot-dns-leaseweb",
"version": "~=1.0.1",
"dependencies": "",
"credentials": "dns_leaseweb_api_token = 01234556789",
"full_plugin_name": "dns-leaseweb"
},
"linode": {
"name": "Linode",
"package_name": "certbot-dns-linode",
@ -424,13 +432,13 @@
"full_plugin_name": "dns-rfc2136"
},
"rockenstein": {
"name": "rockenstein AG",
"package_name": "certbot-dns-rockenstein",
"version": "~=1.0.0",
"dependencies": "",
"credentials": "dns_rockenstein_token=<token>",
"full_plugin_name": "dns-rockenstein"
},
"name": "rockenstein AG",
"package_name": "certbot-dns-rockenstein",
"version": "~=1.0.0",
"dependencies": "",
"credentials": "dns_rockenstein_token=<token>",
"full_plugin_name": "dns-rockenstein"
},
"route53": {
"name": "Route 53 (Amazon)",
"package_name": "certbot-dns-route53",

View File

@ -9,7 +9,7 @@ describe('Full Certificate Provisions', () => {
});
});
it.only('Should be able to create new http certificate', function() {
it('Should be able to create new http certificate', function() {
cy.task('backendApiPost', {
token: token,
path: '/api/nginx/certificates',
@ -35,7 +35,7 @@ describe('Full Certificate Provisions', () => {
it('Should be able to create new DNS certificate with Powerdns', function() {
cy.task('backendApiPost', {
token: token,
path: '/api/certificates',
path: '/api/nginx/certificates',
data: {
domain_names: [
'website2.example.com'
@ -45,7 +45,8 @@ describe('Full Certificate Provisions', () => {
dns_challenge: true,
dns_provider: 'powerdns',
dns_provider_credentials: 'dns_powerdns_api_url = http://ns1.pdns:8081\r\ndns_powerdns_api_key = npm',
letsencrypt_agree: true
letsencrypt_agree: true,
propagation_seconds: 5,
},
provider: 'letsencrypt'
}

View File

@ -1,6 +1,6 @@
/// <reference types="cypress" />
describe('Hosts endpoints', () => {
describe('Proxy Hosts endpoints', () => {
let token;
before(() => {

View File

@ -0,0 +1,124 @@
/// <reference types="cypress" />
describe('Settings endpoints', () => {
let token;
before(() => {
cy.getToken().then((tok) => {
token = tok;
});
});
it('Get all settings', function() {
cy.task('backendApiGet', {
token: token,
path: '/api/settings',
}).then((data) => {
cy.validateSwaggerSchema('get', 200, '/settings', data);
expect(data.length).to.be.greaterThan(0);
});
});
it('Get default-site setting', function() {
cy.task('backendApiGet', {
token: token,
path: '/api/settings/default-site',
}).then((data) => {
cy.validateSwaggerSchema('get', 200, '/settings/{settingID}', data);
expect(data).to.have.property('id');
expect(data.id).to.be.equal('default-site');
});
});
it('Default Site congratulations', function() {
cy.task('backendApiPut', {
token: token,
path: '/api/settings/default-site',
data: {
value: 'congratulations',
},
}).then((data) => {
cy.validateSwaggerSchema('put', 200, '/settings/{settingID}', data);
expect(data).to.have.property('id');
expect(data.id).to.be.equal('default-site');
expect(data).to.have.property('value');
expect(data.value).to.be.equal('congratulations');
});
});
it('Default Site 404', function() {
cy.task('backendApiPut', {
token: token,
path: '/api/settings/default-site',
data: {
value: '404',
},
}).then((data) => {
cy.validateSwaggerSchema('put', 200, '/settings/{settingID}', data);
expect(data).to.have.property('id');
expect(data.id).to.be.equal('default-site');
expect(data).to.have.property('value');
expect(data.value).to.be.equal('404');
});
});
it('Default Site 444', function() {
cy.task('backendApiPut', {
token: token,
path: '/api/settings/default-site',
data: {
value: '444',
},
}).then((data) => {
cy.validateSwaggerSchema('put', 200, '/settings/{settingID}', data);
expect(data).to.have.property('id');
expect(data.id).to.be.equal('default-site');
expect(data).to.have.property('value');
expect(data.value).to.be.equal('444');
});
});
it('Default Site redirect', function() {
cy.task('backendApiPut', {
token: token,
path: '/api/settings/default-site',
data: {
value: 'redirect',
meta: {
redirect: 'https://www.google.com',
},
},
}).then((data) => {
cy.validateSwaggerSchema('put', 200, '/settings/{settingID}', data);
expect(data).to.have.property('id');
expect(data.id).to.be.equal('default-site');
expect(data).to.have.property('value');
expect(data.value).to.be.equal('redirect');
expect(data).to.have.property('meta');
expect(data.meta).to.have.property('redirect');
expect(data.meta.redirect).to.be.equal('https://www.google.com');
});
});
it('Default Site html', function() {
cy.task('backendApiPut', {
token: token,
path: '/api/settings/default-site',
data: {
value: 'html',
meta: {
html: '<p>hello world</p>'
},
},
}).then((data) => {
cy.validateSwaggerSchema('put', 200, '/settings/{settingID}', data);
expect(data).to.have.property('id');
expect(data.id).to.be.equal('default-site');
expect(data).to.have.property('value');
expect(data.value).to.be.equal('html');
expect(data).to.have.property('meta');
expect(data.meta).to.have.property('html');
expect(data.meta.html).to.be.equal('<p>hello world</p>');
});
});
});

View File

@ -7,7 +7,7 @@ const BackendApi = function(config, token) {
this.axios = axios.create({
baseURL: config.baseUrl,
timeout: 60000,
timeout: 90000,
});
};