mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-11-04 01:15:14 +00:00 
			
		
		
		
	Compare commits
	
		
			37 Commits
		
	
	
		
			bump-freed
			...
			aedaaa18e0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					aedaaa18e0 | ||
| 
						 | 
					080bd0b749 | ||
| 
						 | 
					8351dd41f6 | ||
| 
						 | 
					97212f2686 | ||
| 
						 | 
					fe068a8b51 | ||
| 
						 | 
					61e2bde98f | ||
| 
						 | 
					4ea50ca40c | ||
| 
						 | 
					53ed12bcf2 | ||
| 
						 | 
					cb3e4ed59c | ||
| 
						 | 
					b20dc5eade | ||
| 
						 | 
					586afc0c91 | ||
| 
						 | 
					93ea17a9bb | ||
| 
						 | 
					2075f98cad | ||
| 
						 | 
					07a4e5791f | ||
| 
						 | 
					640a1eeb68 | ||
| 
						 | 
					20646e7bb5 | ||
| 
						 | 
					87998a03ce | ||
| 
						 | 
					a0b26b9e98 | ||
| 
						 | 
					d6791f4e38 | ||
| 
						 | 
					62c94f3099 | ||
| 
						 | 
					25a26d6175 | ||
| 
						 | 
					17246e418f | ||
| 
						 | 
					f7d3ca0b07 | ||
| 
						 | 
					a55de386e7 | ||
| 
						 | 
					e9d4f5b827 | ||
| 
						 | 
					1c1cee3836 | ||
| 
						 | 
					eaf6335694 | ||
| 
						 | 
					ffe05ebd41 | ||
| 
						 | 
					2e9a4f1aed | ||
| 
						 | 
					d17c85e4c8 | ||
| 
						 | 
					dad8d0ca00 | ||
| 
						 | 
					d7e0558a35 | ||
| 
						 | 
					ee41bb5562 | ||
| 
						 | 
					0cf6b9caa4 | ||
| 
						 | 
					68a9baf206 | ||
| 
						 | 
					d92421d098 | ||
| 
						 | 
					96c58b203e | 
@@ -313,6 +313,9 @@ const internalCertificate = {
 | 
			
		||||
					.where('is_deleted', 0)
 | 
			
		||||
					.andWhere('id', data.id)
 | 
			
		||||
					.allowGraph('[owner]')
 | 
			
		||||
					.allowGraph('[proxy_hosts]')
 | 
			
		||||
					.allowGraph('[redirection_hosts]')
 | 
			
		||||
					.allowGraph('[dead_hosts]')
 | 
			
		||||
					.first();
 | 
			
		||||
 | 
			
		||||
				if (access_data.permission_visibility !== 'all') {
 | 
			
		||||
@@ -464,6 +467,9 @@ const internalCertificate = {
 | 
			
		||||
					.where('is_deleted', 0)
 | 
			
		||||
					.groupBy('id')
 | 
			
		||||
					.allowGraph('[owner]')
 | 
			
		||||
					.allowGraph('[proxy_hosts]')
 | 
			
		||||
					.allowGraph('[redirection_hosts]')
 | 
			
		||||
					.allowGraph('[dead_hosts]')
 | 
			
		||||
					.orderBy('nice_name', 'ASC');
 | 
			
		||||
 | 
			
		||||
				if (access_data.permission_visibility !== 'all') {
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
	},
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,6 @@
 | 
			
		||||
const db      = require('../db');
 | 
			
		||||
const helpers = require('../lib/helpers');
 | 
			
		||||
const Model   = require('objection').Model;
 | 
			
		||||
const User    = require('./user');
 | 
			
		||||
const now     = require('./now_helper');
 | 
			
		||||
 | 
			
		||||
Model.knex(db);
 | 
			
		||||
@@ -68,6 +67,11 @@ class Certificate extends Model {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static get relationMappings () {
 | 
			
		||||
		const ProxyHost       = require('./proxy_host');
 | 
			
		||||
		const DeadHost        = require('./dead_host');
 | 
			
		||||
		const User            = require('./user');
 | 
			
		||||
		const RedirectionHost = require('./redirection_host');
 | 
			
		||||
 | 
			
		||||
		return {
 | 
			
		||||
			owner: {
 | 
			
		||||
				relation:   Model.HasOneRelation,
 | 
			
		||||
@@ -79,6 +83,39 @@ class Certificate extends Model {
 | 
			
		||||
				modify: function (qb) {
 | 
			
		||||
					qb.where('user.is_deleted', 0);
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			proxy_hosts: {
 | 
			
		||||
				relation:   Model.HasManyRelation,
 | 
			
		||||
				modelClass: ProxyHost,
 | 
			
		||||
				join:       {
 | 
			
		||||
					from: 'certificate.id',
 | 
			
		||||
					to:   'proxy_host.certificate_id'
 | 
			
		||||
				},
 | 
			
		||||
				modify: function (qb) {
 | 
			
		||||
					qb.where('proxy_host.is_deleted', 0);
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			dead_hosts: {
 | 
			
		||||
				relation:   Model.HasManyRelation,
 | 
			
		||||
				modelClass: DeadHost,
 | 
			
		||||
				join:       {
 | 
			
		||||
					from: 'certificate.id',
 | 
			
		||||
					to:   'dead_host.certificate_id'
 | 
			
		||||
				},
 | 
			
		||||
				modify: function (qb) {
 | 
			
		||||
					qb.where('dead_host.is_deleted', 0);
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			redirection_hosts: {
 | 
			
		||||
				relation:   Model.HasManyRelation,
 | 
			
		||||
				modelClass: RedirectionHost,
 | 
			
		||||
				join:       {
 | 
			
		||||
					from: 'certificate.id',
 | 
			
		||||
					to:   'redirection_host.certificate_id'
 | 
			
		||||
				},
 | 
			
		||||
				modify: function (qb) {
 | 
			
		||||
					qb.where('redirection_host.is_deleted', 0);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,9 @@
 | 
			
		||||
		"incoming_port": {
 | 
			
		||||
			"type": "integer",
 | 
			
		||||
			"minimum": 1,
 | 
			
		||||
			"maximum": 65535
 | 
			
		||||
			"maximum": 65535,
 | 
			
		||||
			"if": {"properties": {"tcp_forwarding": {"const": true}}},
 | 
			
		||||
			"then": {"not": {"oneOf": [{"const": 80}, {"const": 443}]}}
 | 
			
		||||
		},
 | 
			
		||||
		"forwarding_host": {
 | 
			
		||||
			"anyOf": [
 | 
			
		||||
 
 | 
			
		||||
@@ -49,8 +49,7 @@
 | 
			
		||||
										"minLength": 1
 | 
			
		||||
									},
 | 
			
		||||
									"password": {
 | 
			
		||||
										"type": "string",
 | 
			
		||||
										"minLength": 1
 | 
			
		||||
										"type": "string"
 | 
			
		||||
									}
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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 %}
 | 
			
		||||
@@ -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" %}
 | 
			
		||||
 
 | 
			
		||||
@@ -830,9 +830,9 @@ crc32-stream@^4.0.2:
 | 
			
		||||
    readable-stream "^3.4.0"
 | 
			
		||||
 | 
			
		||||
cross-spawn@^7.0.2:
 | 
			
		||||
  version "7.0.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
 | 
			
		||||
  integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
 | 
			
		||||
  version "7.0.6"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
 | 
			
		||||
  integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    path-key "^3.1.0"
 | 
			
		||||
    shebang-command "^2.0.0"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
location ~* ^.*\.(css|js|jpe?g|gif|png|webp|woff|eot|ttf|svg|ico|css\.map|js\.map)$ {
 | 
			
		||||
location ~* ^.*\.(css|js|jpe?g|gif|png|webp|woff|woff2|eot|ttf|svg|ico|css\.map|js\.map)$ {
 | 
			
		||||
	if_modified_since off;
 | 
			
		||||
 | 
			
		||||
	# use the public cache
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,6 @@ networks:
 | 
			
		||||
Let's look at a Portainer example:
 | 
			
		||||
 | 
			
		||||
```yml
 | 
			
		||||
version: '3.8'
 | 
			
		||||
services:
 | 
			
		||||
 | 
			
		||||
  portainer:
 | 
			
		||||
@@ -92,8 +91,6 @@ This image supports the use of Docker secrets to import from files and keep sens
 | 
			
		||||
You can set any environment variable from a file by appending `__FILE` (double-underscore FILE) to the environmental variable name.
 | 
			
		||||
 | 
			
		||||
```yml
 | 
			
		||||
version: '3.8'
 | 
			
		||||
 | 
			
		||||
secrets:
 | 
			
		||||
  # Secrets are single-line text files where the sole content is the secret
 | 
			
		||||
  # Paths in this example assume that secrets are kept in local folder called ".secrets"
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,6 @@ outline: deep
 | 
			
		||||
Create a `docker-compose.yml` file:
 | 
			
		||||
 | 
			
		||||
```yml
 | 
			
		||||
version: '3.8'
 | 
			
		||||
services:
 | 
			
		||||
  app:
 | 
			
		||||
    image: 'jc21/nginx-proxy-manager:latest'
 | 
			
		||||
@@ -55,7 +54,6 @@ are going to use.
 | 
			
		||||
Here is an example of what your `docker-compose.yml` will look like when using a MariaDB container:
 | 
			
		||||
 | 
			
		||||
```yml
 | 
			
		||||
version: '3.8'
 | 
			
		||||
services:
 | 
			
		||||
  app:
 | 
			
		||||
    image: 'jc21/nginx-proxy-manager:latest'
 | 
			
		||||
@@ -137,5 +135,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
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -50,8 +50,7 @@ module.exports = Mn.View.extend({
 | 
			
		||||
    onRender: function () {
 | 
			
		||||
        let view = this;
 | 
			
		||||
 | 
			
		||||
        if (typeof view.stats.hosts === 'undefined') {
 | 
			
		||||
            Api.Reports.getHostStats()
 | 
			
		||||
        Api.Reports.getHostStats()
 | 
			
		||||
                .then(response => {
 | 
			
		||||
                    if (!view.isDestroyed()) {
 | 
			
		||||
                        view.stats.hosts = response;
 | 
			
		||||
@@ -61,7 +60,6 @@ module.exports = Mn.View.extend({
 | 
			
		||||
                .catch(err => {
 | 
			
		||||
                    console.log(err);
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<td class="text-center">
 | 
			
		||||
    <div class="avatar d-block" style="background-image: url(<%- owner.avatar || '/images/default-avatar.jpg' %>)" title="Owned by <%- owner.name %>">
 | 
			
		||||
        <span class="avatar-status <%- owner.is_disabled ? 'bg-red' : 'bg-green' %>"></span>
 | 
			
		||||
    <div class="avatar d-block" style="background-image: url(<%- (owner && owner.avatar) || '/images/default-avatar.jpg' %>)" title="Owned by <%- (owner && owner.name) || 'a deleted user' %>">
 | 
			
		||||
        <span class="avatar-status <%- owner && !owner.is_disabled ? 'bg-green' : 'bg-red' %>"></span>
 | 
			
		||||
    </div>
 | 
			
		||||
</td>
 | 
			
		||||
<td>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<td class="text-center">
 | 
			
		||||
    <div class="avatar d-block" style="background-image: url(<%- owner.avatar || '/images/default-avatar.jpg' %>)" title="Owned by <%- owner.name %>">
 | 
			
		||||
        <span class="avatar-status <%- owner.is_disabled ? 'bg-red' : 'bg-green' %>"></span>
 | 
			
		||||
    <div class="avatar d-block" style="background-image: url(<%- (owner && owner.avatar) || '/images/default-avatar.jpg' %>)" title="Owned by <%- (owner && owner.name) || 'a deleted user' %>">
 | 
			
		||||
        <span class="avatar-status <%- owner && !owner.is_disabled ? 'bg-green' : 'bg-red' %>"></span>
 | 
			
		||||
    </div>
 | 
			
		||||
</td>
 | 
			
		||||
<td>
 | 
			
		||||
@@ -33,6 +33,13 @@
 | 
			
		||||
<td class="<%- isExpired() ? 'text-danger' : '' %>">
 | 
			
		||||
    <%- formatDbDate(expires_on, 'Do MMMM YYYY, h:mm a') %>
 | 
			
		||||
</td>
 | 
			
		||||
<td>
 | 
			
		||||
    <% if (active_domain_names().length > 0) { %>
 | 
			
		||||
        <span class="status-icon bg-success"></span> <%- i18n('certificates', 'in-use') %>
 | 
			
		||||
    <% } else { %>
 | 
			
		||||
        <span class="status-icon bg-danger"></span> <%- i18n('certificates', 'inactive') %>
 | 
			
		||||
    <% } %>
 | 
			
		||||
</td>
 | 
			
		||||
<% if (canManage) { %>
 | 
			
		||||
<td class="text-right">
 | 
			
		||||
    <div class="item-action dropdown">
 | 
			
		||||
@@ -48,6 +55,13 @@
 | 
			
		||||
                <div class="dropdown-divider"></div>
 | 
			
		||||
            <% } %>
 | 
			
		||||
            <a href="#" class="delete dropdown-item"><i class="dropdown-icon fe fe-trash-2"></i> <%- i18n('str', 'delete') %></a>
 | 
			
		||||
            <% if (active_domain_names().length > 0) { %>
 | 
			
		||||
                <div class="dropdown-divider"></div>
 | 
			
		||||
                <span class="dropdown-header"><%- i18n('certificates', 'active-domain_names') %></span>
 | 
			
		||||
                <% active_domain_names().forEach(function(host) { %>
 | 
			
		||||
                    <a href="https://<%- host %>" class="dropdown-item" target="_blank"><%- host %></a>
 | 
			
		||||
                <% }); %>
 | 
			
		||||
            <% } %>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</td>
 | 
			
		||||
 
 | 
			
		||||
@@ -44,14 +44,24 @@ module.exports = Mn.View.extend({
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    templateContext: {
 | 
			
		||||
        canManage: App.Cache.User.canManage('certificates'),
 | 
			
		||||
        isExpired: function () {
 | 
			
		||||
            return moment(this.expires_on).isBefore(moment());
 | 
			
		||||
        },
 | 
			
		||||
        dns_providers: dns_providers
 | 
			
		||||
    templateContext: function () {
 | 
			
		||||
        return {
 | 
			
		||||
            canManage: App.Cache.User.canManage('certificates'),
 | 
			
		||||
            isExpired: function () {
 | 
			
		||||
                return moment(this.expires_on).isBefore(moment());
 | 
			
		||||
            },
 | 
			
		||||
            dns_providers: dns_providers,
 | 
			
		||||
            active_domain_names: function () {
 | 
			
		||||
                const { proxy_hosts = [], redirect_hosts = [], dead_hosts = [] } = this;
 | 
			
		||||
                return [...proxy_hosts, ...redirect_hosts, ...dead_hosts].reduce((acc, host) => {
 | 
			
		||||
                    acc.push(...(host.domain_names || []));
 | 
			
		||||
                    return acc;
 | 
			
		||||
                }, []);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    initialize: function () {
 | 
			
		||||
        this.listenTo(this.model, 'change', this.render);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
    <th><%- i18n('str', 'name') %></th>
 | 
			
		||||
    <th><%- i18n('all-hosts', 'cert-provider') %></th>
 | 
			
		||||
    <th><%- i18n('str', 'expires') %></th>
 | 
			
		||||
    <th><%- i18n('str', 'status') %></th>
 | 
			
		||||
    <% if (canManage) { %>
 | 
			
		||||
    <th> </th>
 | 
			
		||||
    <% } %>
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,7 @@ module.exports = Mn.View.extend({
 | 
			
		||||
            e.preventDefault();
 | 
			
		||||
            let query = this.ui.query.val();
 | 
			
		||||
 | 
			
		||||
            this.fetch(['owner'], query)
 | 
			
		||||
            this.fetch(['owner','proxy_hosts', 'dead_hosts', 'redirection_hosts'], query)
 | 
			
		||||
                .then(response => this.showData(response))
 | 
			
		||||
                .catch(err => {
 | 
			
		||||
                    this.showError(err);
 | 
			
		||||
@@ -89,7 +89,7 @@ module.exports = Mn.View.extend({
 | 
			
		||||
    onRender: function () {
 | 
			
		||||
        let view = this;
 | 
			
		||||
 | 
			
		||||
        view.fetch(['owner'])
 | 
			
		||||
        view.fetch(['owner','proxy_hosts', 'dead_hosts', 'redirection_hosts'])
 | 
			
		||||
            .then(response => {
 | 
			
		||||
                if (!view.isDestroyed()) {
 | 
			
		||||
                    if (response && response.length) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<td class="text-center">
 | 
			
		||||
    <div class="avatar d-block" style="background-image: url(<%- owner.avatar || '/images/default-avatar.jpg' %>)" title="Owned by <%- owner.name %>">
 | 
			
		||||
        <span class="avatar-status <%- owner.is_disabled ? 'bg-red' : 'bg-green' %>"></span>
 | 
			
		||||
    <div class="avatar d-block" style="background-image: url(<%- (owner && owner.avatar) || '/images/default-avatar.jpg' %>)" title="Owned by <%- (owner && owner.name) || 'a deleted user' %>">
 | 
			
		||||
        <span class="avatar-status <%- owner && !owner.is_disabled ? 'bg-green' : 'bg-red' %>"></span>
 | 
			
		||||
    </div>
 | 
			
		||||
</td>
 | 
			
		||||
<td>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<td class="text-center">
 | 
			
		||||
    <div class="avatar d-block" style="background-image: url(<%- owner.avatar || '/images/default-avatar.jpg' %>)" title="Owned by <%- owner.name %>">
 | 
			
		||||
        <span class="avatar-status <%- owner.is_disabled ? 'bg-red' : 'bg-green' %>"></span>
 | 
			
		||||
    <div class="avatar d-block" style="background-image: url(<%- (owner && owner.avatar) || '/images/default-avatar.jpg' %>)" title="Owned by <%- (owner && owner.name) || 'a deleted user' %>">
 | 
			
		||||
        <span class="avatar-status <%- owner && !owner.is_disabled ? 'bg-green' : 'bg-red' %>"></span>
 | 
			
		||||
    </div>
 | 
			
		||||
</td>
 | 
			
		||||
<td>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<td class="text-center">
 | 
			
		||||
    <div class="avatar d-block" style="background-image: url(<%- owner.avatar || '/images/default-avatar.jpg' %>)" title="Owned by <%- owner.name %>">
 | 
			
		||||
        <span class="avatar-status <%- owner.is_disabled ? 'bg-red' : 'bg-green' %>"></span>
 | 
			
		||||
    <div class="avatar d-block" style="background-image: url(<%- (owner && owner.avatar) || '/images/default-avatar.jpg' %>)" title="Owned by <%- (owner && owner.name) || 'a deleted user' %>">
 | 
			
		||||
        <span class="avatar-status <%- owner && !owner.is_disabled ? 'bg-green' : 'bg-red' %>"></span>
 | 
			
		||||
    </div>
 | 
			
		||||
</td>
 | 
			
		||||
<td>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<td class="text-center">
 | 
			
		||||
    <div class="avatar d-block" style="background-image: url(<%- owner.avatar || '/images/default-avatar.jpg' %>)" title="Owned by <%- owner.name %>">
 | 
			
		||||
        <span class="avatar-status <%- owner.is_disabled ? 'bg-red' : 'bg-green' %>"></span>
 | 
			
		||||
    <div class="avatar d-block" style="background-image: url(<%- (owner && owner.avatar) || '/images/default-avatar.jpg' %>)" title="Owned by <%- (owner && owner.name) || 'a deleted user' %>">
 | 
			
		||||
        <span class="avatar-status <%- owner && !owner.is_disabled ? 'bg-green' : 'bg-red' %>"></span>
 | 
			
		||||
    </div>
 | 
			
		||||
</td>
 | 
			
		||||
<td>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
<div class="modal-content">
 | 
			
		||||
    <div class="modal-header">
 | 
			
		||||
        <h5 class="modal-title"><%- i18n('users', 'form-title', {id: id}) %></h5>
 | 
			
		||||
        <button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="modal-body">
 | 
			
		||||
        <form>
 | 
			
		||||
    <form>
 | 
			
		||||
        <div class="modal-header">
 | 
			
		||||
            <h5 class="modal-title"><%- i18n('users', 'form-title', {id: id}) %></h5>
 | 
			
		||||
            <button type="button" class="close cancel" aria-label="Close" data-dismiss="modal"> </button>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="modal-body">
 | 
			
		||||
            <div class="row">
 | 
			
		||||
                <div class="col-sm-6 col-md-6">
 | 
			
		||||
                    <div class="form-group">
 | 
			
		||||
@@ -49,10 +49,10 @@
 | 
			
		||||
                </div>
 | 
			
		||||
                <% } %>
 | 
			
		||||
            </div>
 | 
			
		||||
        </form>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="modal-footer">
 | 
			
		||||
        <button type="button" class="btn btn-secondary cancel" data-dismiss="modal"><%- i18n('str', 'cancel') %></button>
 | 
			
		||||
        <button type="button" class="btn btn-teal save"><%- i18n('str', 'save') %></button>
 | 
			
		||||
    </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="modal-footer">
 | 
			
		||||
            <button type="button" class="btn btn-secondary cancel" data-dismiss="modal"><%- i18n('str', 'cancel') %></button>
 | 
			
		||||
            <button type="submit" class="btn btn-teal save"><%- i18n('str', 'save') %></button>
 | 
			
		||||
        </div>
 | 
			
		||||
    </form>
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ module.exports = Mn.View.extend({
 | 
			
		||||
 | 
			
		||||
    events: {
 | 
			
		||||
 | 
			
		||||
        'click @ui.save': function (e) {
 | 
			
		||||
        'submit @ui.form': function (e) {
 | 
			
		||||
            e.preventDefault();
 | 
			
		||||
            this.ui.error.hide();
 | 
			
		||||
            let view = this;
 | 
			
		||||
 
 | 
			
		||||
@@ -206,7 +206,10 @@
 | 
			
		||||
      "reachability-other": "There is a server found at this domain but it returned an unexpected status code {code}. Is it the NPM server? Please make sure your domain points to the IP where your NPM instance is running.",
 | 
			
		||||
      "download": "Download",
 | 
			
		||||
      "renew-title": "Renew Let's Encrypt Certificate",
 | 
			
		||||
      "search": "Search Certificate…"
 | 
			
		||||
      "search": "Search Certificate…",
 | 
			
		||||
      "in-use"  : "In use",
 | 
			
		||||
      "inactive": "Inactive",
 | 
			
		||||
      "active-domain_names": "Active domain names"
 | 
			
		||||
    },
 | 
			
		||||
    "access-lists": {
 | 
			
		||||
      "title": "Access Lists",
 | 
			
		||||
 
 | 
			
		||||
@@ -2648,9 +2648,9 @@ electron-to-chromium@^1.3.47:
 | 
			
		||||
  integrity sha512-67V62Z4CFOiAtox+o+tosGfVk0QX4DJgH609tjT8QymbJZVAI/jWnAthnr8c5hnRNziIRwkc9EMQYejiVz3/9Q==
 | 
			
		||||
 | 
			
		||||
elliptic@^6.5.3, elliptic@^6.5.4:
 | 
			
		||||
  version "6.5.7"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.7.tgz#8ec4da2cb2939926a1b9a73619d768207e647c8b"
 | 
			
		||||
  integrity sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==
 | 
			
		||||
  version "6.6.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.0.tgz#5919ec723286c1edf28685aa89261d4761afa210"
 | 
			
		||||
  integrity sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    bn.js "^4.11.9"
 | 
			
		||||
    brorand "^1.1.0"
 | 
			
		||||
 
 | 
			
		||||
@@ -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",
 | 
			
		||||
 
 | 
			
		||||
@@ -132,9 +132,9 @@
 | 
			
		||||
  integrity sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==
 | 
			
		||||
 | 
			
		||||
"@eslint/plugin-kit@^0.2.0":
 | 
			
		||||
  version "0.2.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz#8712dccae365d24e9eeecb7b346f85e750ba343d"
 | 
			
		||||
  integrity sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==
 | 
			
		||||
  version "0.2.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz#812980a6a41ecf3a8341719f92a6d1e784a2e0e8"
 | 
			
		||||
  integrity sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    levn "^0.4.1"
 | 
			
		||||
 | 
			
		||||
@@ -628,9 +628,9 @@ core-util-is@1.0.2:
 | 
			
		||||
  integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
 | 
			
		||||
 | 
			
		||||
cross-spawn@^7.0.0, cross-spawn@^7.0.2:
 | 
			
		||||
  version "7.0.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
 | 
			
		||||
  integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
 | 
			
		||||
  version "7.0.6"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
 | 
			
		||||
  integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    path-key "^3.1.0"
 | 
			
		||||
    shebang-command "^2.0.0"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user