Compare commits

..

2 Commits

Author SHA1 Message Date
Julian Gassner
a812e0280c Merge e6f61e297f into 0d5d2b1b7c 2025-02-06 07:48:50 +10:00
Julian Gassner
e6f61e297f Add button to add custom certificate in certificate list 2025-01-22 15:33:02 +00:00
15 changed files with 538 additions and 522 deletions

View File

@@ -1 +1 @@
2.12.3 2.12.2

View File

@@ -1,7 +1,7 @@
<p align="center"> <p align="center">
<img src="https://nginxproxymanager.com/github.png"> <img src="https://nginxproxymanager.com/github.png">
<br><br> <br><br>
<img src="https://img.shields.io/badge/version-2.12.3-green.svg?style=for-the-badge"> <img src="https://img.shields.io/badge/version-2.12.2-green.svg?style=for-the-badge">
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager"> <a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
<img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge"> <img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge">
</a> </a>

View File

@@ -508,13 +508,8 @@ const internalAccessList = {
if (typeof item.password !== 'undefined' && item.password.length) { if (typeof item.password !== 'undefined' && item.password.length) {
logger.info('Adding: ' + item.username); logger.info('Adding: ' + item.username);
utils.execFile('openssl', ['passwd', '-apr1', item.password]) utils.execFile('/usr/bin/htpasswd', ['-b', htpasswd_file, item.username, item.password])
.then((res) => { .then((/*result*/) => {
try {
fs.appendFileSync(htpasswd_file, item.username + ':' + res + '\n', {encoding: 'utf8'});
} catch (err) {
reject(err);
}
next(); next();
}) })
.catch((err) => { .catch((err) => {

View File

@@ -26,7 +26,7 @@ module.exports = {
* Users * Users
*/ */
showUsers: function () { showUsers: function () {
const controller = this; let controller = this;
if (Cache.User.isAdmin()) { if (Cache.User.isAdmin()) {
require(['./main', './users/main'], (App, View) => { require(['./main', './users/main'], (App, View) => {
controller.navigate('/users'); controller.navigate('/users');
@@ -93,7 +93,8 @@ module.exports = {
* Dashboard * Dashboard
*/ */
showDashboard: function () { showDashboard: function () {
const controller = this; let controller = this;
require(['./main', './dashboard/main'], (App, View) => { require(['./main', './dashboard/main'], (App, View) => {
controller.navigate('/'); controller.navigate('/');
App.UI.showAppContent(new View()); App.UI.showAppContent(new View());
@@ -105,7 +106,7 @@ module.exports = {
*/ */
showNginxProxy: function () { showNginxProxy: function () {
if (Cache.User.isAdmin() || Cache.User.canView('proxy_hosts')) { if (Cache.User.isAdmin() || Cache.User.canView('proxy_hosts')) {
const controller = this; let controller = this;
require(['./main', './nginx/proxy/main'], (App, View) => { require(['./main', './nginx/proxy/main'], (App, View) => {
controller.navigate('/nginx/proxy'); controller.navigate('/nginx/proxy');
@@ -145,7 +146,8 @@ module.exports = {
*/ */
showNginxRedirection: function () { showNginxRedirection: function () {
if (Cache.User.isAdmin() || Cache.User.canView('redirection_hosts')) { if (Cache.User.isAdmin() || Cache.User.canView('redirection_hosts')) {
const controller = this; let controller = this;
require(['./main', './nginx/redirection/main'], (App, View) => { require(['./main', './nginx/redirection/main'], (App, View) => {
controller.navigate('/nginx/redirection'); controller.navigate('/nginx/redirection');
App.UI.showAppContent(new View()); App.UI.showAppContent(new View());
@@ -184,7 +186,8 @@ module.exports = {
*/ */
showNginxStream: function () { showNginxStream: function () {
if (Cache.User.isAdmin() || Cache.User.canView('streams')) { if (Cache.User.isAdmin() || Cache.User.canView('streams')) {
const controller = this; let controller = this;
require(['./main', './nginx/stream/main'], (App, View) => { require(['./main', './nginx/stream/main'], (App, View) => {
controller.navigate('/nginx/stream'); controller.navigate('/nginx/stream');
App.UI.showAppContent(new View()); App.UI.showAppContent(new View());
@@ -223,7 +226,8 @@ module.exports = {
*/ */
showNginxDead: function () { showNginxDead: function () {
if (Cache.User.isAdmin() || Cache.User.canView('dead_hosts')) { if (Cache.User.isAdmin() || Cache.User.canView('dead_hosts')) {
const controller = this; let controller = this;
require(['./main', './nginx/dead/main'], (App, View) => { require(['./main', './nginx/dead/main'], (App, View) => {
controller.navigate('/nginx/404'); controller.navigate('/nginx/404');
App.UI.showAppContent(new View()); App.UI.showAppContent(new View());
@@ -274,7 +278,8 @@ module.exports = {
*/ */
showNginxAccess: function () { showNginxAccess: function () {
if (Cache.User.isAdmin() || Cache.User.canView('access_lists')) { if (Cache.User.isAdmin() || Cache.User.canView('access_lists')) {
const controller = this; let controller = this;
require(['./main', './nginx/access/main'], (App, View) => { require(['./main', './nginx/access/main'], (App, View) => {
controller.navigate('/nginx/access'); controller.navigate('/nginx/access');
App.UI.showAppContent(new View()); App.UI.showAppContent(new View());
@@ -313,7 +318,8 @@ module.exports = {
*/ */
showNginxCertificates: function () { showNginxCertificates: function () {
if (Cache.User.isAdmin() || Cache.User.canView('certificates')) { if (Cache.User.isAdmin() || Cache.User.canView('certificates')) {
const controller = this; let controller = this;
require(['./main', './nginx/certificates/main'], (App, View) => { require(['./main', './nginx/certificates/main'], (App, View) => {
controller.navigate('/nginx/certificates'); controller.navigate('/nginx/certificates');
App.UI.showAppContent(new View()); App.UI.showAppContent(new View());
@@ -377,7 +383,7 @@ module.exports = {
* Audit Log * Audit Log
*/ */
showAuditLog: function () { showAuditLog: function () {
const controller = this; let controller = this;
if (Cache.User.isAdmin()) { if (Cache.User.isAdmin()) {
require(['./main', './audit-log/main'], (App, View) => { require(['./main', './audit-log/main'], (App, View) => {
controller.navigate('/audit-log'); controller.navigate('/audit-log');
@@ -405,7 +411,7 @@ module.exports = {
* Settings * Settings
*/ */
showSettings: function () { showSettings: function () {
const controller = this; let controller = this;
if (Cache.User.isAdmin()) { if (Cache.User.isAdmin()) {
require(['./main', './settings/main'], (App, View) => { require(['./main', './settings/main'], (App, View) => {
controller.navigate('/settings'); controller.navigate('/settings');

View File

@@ -24,7 +24,7 @@ module.exports = Mn.View.extend({
}, },
templateContext: function () { templateContext: function () {
const view = this; let view = this;
return { return {
getUserName: function () { getUserName: function () {
@@ -48,8 +48,8 @@ module.exports = Mn.View.extend({
}, },
onRender: function () { onRender: function () {
const view = this; let view = this;
if (typeof view.stats.hosts === 'undefined') {
Api.Reports.getHostStats() Api.Reports.getHostStats()
.then(response => { .then(response => {
if (!view.isDestroyed()) { if (!view.isDestroyed()) {
@@ -60,7 +60,6 @@ module.exports = Mn.View.extend({
.catch(err => { .catch(err => {
console.log(err); console.log(err);
}); });
}
}, },
/** /**
@@ -71,7 +70,8 @@ module.exports = Mn.View.extend({
// calculate the available columns based on permissions for the objects // calculate the available columns based on permissions for the objects
// and store as a variable // and store as a variable
const perms = ['proxy_hosts', 'redirection_hosts', 'streams', 'dead_hosts']; //let view = this;
let perms = ['proxy_hosts', 'redirection_hosts', 'streams', 'dead_hosts'];
perms.map(perm => { perms.map(perm => {
this.columns += Cache.User.isAdmin() || Cache.User.canView(perm) ? 1 : 0; this.columns += Cache.User.isAdmin() || Cache.User.canView(perm) ? 1 : 0;

View File

@@ -6,6 +6,10 @@ if (subtitle) { %>
<p class="h4 text-muted font-weight-normal mb-7"><%- subtitle %></p> <p class="h4 text-muted font-weight-normal mb-7"><%- subtitle %></p>
<% } <% }
if (link) { %> if (links && links.length) { %>
<a class="btn btn-<%- btn_color %>" href="#"><%- link %></a> <% links.forEach(function(link, index) { %>
<div style="margin-bottom: 10px;">
<a class="btn btn-<%- btn_color %>" href="#" data-index="<%- index %>"><%- link %></a>
</div>
<% }); %>
<% } %> <% } %>

View File

@@ -6,7 +6,9 @@ module.exports = Mn.View.extend({
template: template, template: template,
options: { options: {
btn_color: 'teal' btn_color: 'teal',
links: [], // Added to accept multiple links
actions: [] // Added to accept multiple actions
}, },
ui: { ui: {
@@ -16,7 +18,8 @@ module.exports = Mn.View.extend({
events: { events: {
'click @ui.action': function (e) { 'click @ui.action': function (e) {
e.preventDefault(); e.preventDefault();
this.getOption('action')(); const index = $(e.currentTarget).data('index');
this.getOption('actions')[index]();
} }
}, },
@@ -24,8 +27,9 @@ module.exports = Mn.View.extend({
return { return {
title: this.getOption('title'), title: this.getOption('title'),
subtitle: this.getOption('subtitle'), subtitle: this.getOption('subtitle'),
link: this.getOption('link'), links: this.getOption('links'), // Changed to array
action: typeof this.getOption('action') === 'function', actions: this.getOption('actions'), // Changed to array
hasActions: this.getOption('actions').length > 0,
btn_color: this.getOption('btn_color') btn_color: this.getOption('btn_color')
}; };
} }

View File

@@ -45,12 +45,14 @@ module.exports = Mn.View.extend({
this.showChildView('list_region', new EmptyView({ this.showChildView('list_region', new EmptyView({
title: App.i18n('access-lists', 'empty'), title: App.i18n('access-lists', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}), subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('access-lists', 'add') : null, links: manage ? [App.i18n('access-lists', 'add')] : [],
btn_color: 'teal', btn_color: 'teal',
permission: 'access_lists', permission: 'access_lists',
action: function () { actions: [
function () {
App.Controller.showNginxAccessListForm(); App.Controller.showNginxAccessListForm();
} }
]
})); }));
}, },

View File

@@ -45,12 +45,16 @@ module.exports = Mn.View.extend({
this.showChildView('list_region', new EmptyView({ this.showChildView('list_region', new EmptyView({
title: App.i18n('certificates', 'empty'), title: App.i18n('certificates', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}), subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('certificates', 'add') : null, links: manage ? [App.i18n('certificates', 'add-letsencrypt'), App.i18n('certificates', 'add-custom')] : [],
btn_color: 'pink', actions: [
permission: 'certificates', function () {
action: function () {
App.Controller.showNginxCertificateForm(); App.Controller.showNginxCertificateForm();
} },
function () {
App.Controller.showNginxCertificateForm(new CertificateModel.Model({provider: 'custom'}));
}],
btn_color: 'pink',
permission: 'certificates'
})); }));
}, },

View File

@@ -45,12 +45,14 @@ module.exports = Mn.View.extend({
this.showChildView('list_region', new EmptyView({ this.showChildView('list_region', new EmptyView({
title: App.i18n('dead-hosts', 'empty'), title: App.i18n('dead-hosts', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}), subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('dead-hosts', 'add') : null, links: manage ? [App.i18n('dead-hosts', 'add')] : [],
btn_color: 'danger', btn_color: 'danger',
permission: 'dead_hosts', permission: 'dead_hosts',
action: function () { actions: [
function () {
App.Controller.showNginxDeadForm(); App.Controller.showNginxDeadForm();
} }
]
})); }));
}, },

View File

@@ -41,16 +41,17 @@ module.exports = Mn.View.extend({
showEmpty: function() { showEmpty: function() {
let manage = App.Cache.User.canManage('proxy_hosts'); let manage = App.Cache.User.canManage('proxy_hosts');
this.showChildView('list_region', new EmptyView({ this.showChildView('list_region', new EmptyView({
title: App.i18n('proxy-hosts', 'empty'), title: App.i18n('proxy-hosts', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}), subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('proxy-hosts', 'add') : null, links: manage ? [App.i18n('proxy-hosts', 'add')] : [],
btn_color: 'success', actions: [
permission: 'proxy_hosts', function () {
action: function () {
App.Controller.showNginxProxyForm(); App.Controller.showNginxProxyForm();
} }
],
btn_color: 'success',
permission: 'proxy_hosts',
})); }));
}, },

View File

@@ -44,12 +44,14 @@ module.exports = Mn.View.extend({
this.showChildView('list_region', new EmptyView({ this.showChildView('list_region', new EmptyView({
title: App.i18n('redirection-hosts', 'empty'), title: App.i18n('redirection-hosts', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}), subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('redirection-hosts', 'add') : null, links: manage ? [App.i18n('redirection-hosts', 'add')] : [],
btn_color: 'yellow', btn_color: 'yellow',
permission: 'redirection_hosts', permission: 'redirection_hosts',
action: function () { actions: [
function () {
App.Controller.showNginxRedirectionForm(); App.Controller.showNginxRedirectionForm();
} }
]
})); }));
}, },

View File

@@ -45,12 +45,14 @@ module.exports = Mn.View.extend({
this.showChildView('list_region', new EmptyView({ this.showChildView('list_region', new EmptyView({
title: App.i18n('streams', 'empty'), title: App.i18n('streams', 'empty'),
subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}), subtitle: App.i18n('all-hosts', 'empty-subtitle', {manage: manage}),
link: manage ? App.i18n('streams', 'add') : null, links: manage ? [App.i18n('streams', 'add')] : [],
btn_color: 'blue', btn_color: 'blue',
permission: 'streams', permission: 'streams',
action: function () { actions: [
function () {
App.Controller.showNginxStreamForm(); App.Controller.showNginxStreamForm();
} }
]
})); }));
}, },

View File

@@ -187,6 +187,8 @@
"title": "SSL Certificates", "title": "SSL Certificates",
"empty": "There are no SSL Certificates", "empty": "There are no SSL Certificates",
"add": "Add SSL Certificate", "add": "Add SSL Certificate",
"add-letsencrypt": "Add SSL Certificate with Let's Encrypt",
"add-custom": "Add Custom SSL Certificate",
"form-title": "Add {provider, select, letsencrypt{Let's Encrypt} other{Custom}} Certificate", "form-title": "Add {provider, select, letsencrypt{Let's Encrypt} other{Custom}} Certificate",
"delete": "Delete SSL Certificate", "delete": "Delete SSL Certificate",
"delete-confirm": "Are you sure you want to delete this SSL Certificate? Any hosts using it will need to be updated later.", "delete-confirm": "Are you sure you want to delete this SSL Certificate? Any hosts using it will need to be updated later.",

View File

@@ -161,11 +161,11 @@
}, },
"domainoffensive": { "domainoffensive": {
"name": "DomainOffensive (do.de)", "name": "DomainOffensive (do.de)",
"package_name": "certbot-dns-domainoffensive", "package_name": "certbot-dns-do",
"version": "~=2.0.0", "version": "~=0.31.0",
"dependencies": "", "dependencies": "",
"credentials": "dns_do_api_token = YOUR_DO_DE_AUTH_TOKEN", "credentials": "dns_do_api_token = YOUR_DO_DE_AUTH_TOKEN",
"full_plugin_name": "dns-domainoffensive" "full_plugin_name": "dns-do"
}, },
"domeneshop": { "domeneshop": {
"name": "Domeneshop", "name": "Domeneshop",
@@ -534,13 +534,5 @@
"dependencies": "", "dependencies": "",
"credentials": "edgedns_client_secret = as3d1asd5d1a32sdfsdfs2d1asd5=\nedgedns_host = sdflskjdf-dfsdfsdf-sdfsdfsdf.luna.akamaiapis.net\nedgedns_access_token = kjdsi3-34rfsdfsdf-234234fsdfsdf\nedgedns_client_token = dkfjdf-342fsdfsd-23fsdfsdfsdf", "credentials": "edgedns_client_secret = as3d1asd5d1a32sdfsdfs2d1asd5=\nedgedns_host = sdflskjdf-dfsdfsdf-sdfsdfsdf.luna.akamaiapis.net\nedgedns_access_token = kjdsi3-34rfsdfsdf-234234fsdfsdf\nedgedns_client_token = dkfjdf-342fsdfsd-23fsdfsdfsdf",
"full_plugin_name": "edgedns" "full_plugin_name": "edgedns"
},
"zoneedit": {
"name": "ZoneEdit",
"package_name": "certbot-dns-zoneedit",
"version": "~=0.3.2",
"dependencies": "--no-deps dnspython",
"credentials": "dns_zoneedit_user = <login-user-id>\ndns_zoneedit_token = <dyn-authentication-token>",
"full_plugin_name": "dns-zoneedit"
} }
} }