Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
0bc12f3bdf | |||
31aa9c9644 | |||
ddbfdf6f6e | |||
43c7063538 | |||
3f089fb239 | |||
2d0f7d5126 | |||
06272d3d2c | |||
3885c0ad6d | |||
099ec00155 | |||
92fcae9c54 | |||
22e8961c80 | |||
4d5adefa41 | |||
feaa0e51bd | |||
af83cb57d0 | |||
8b4f3507c3 | |||
bda3dba369 | |||
beb313af40 | |||
4fad9d672f | |||
0fca64929e | |||
9e476e5b24 | |||
0819a265f5 | |||
ad8eac4f07 | |||
b49de0e23e | |||
efbd024da9 | |||
e7ddcb91fc |
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Checklist**
|
||||
- Have you pulled and found the error with `jc21/nginx-proxy-manager:latest` docker image?
|
||||
- Are you sure you're not using someone else's docker image?
|
||||
- If having problems with Lets Encrypt, have you made absolutely sure your site is accessible from outside of your network?
|
||||
|
||||
**Describe the bug**
|
||||
- A clear and concise description of what the bug is.
|
||||
- What version of Nginx Proxy Manager is reported on the login page?
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Operating System**
|
||||
- Please specify if using a Rpi, Mac, orchestration tool or any other setups that might affect the reproduction of this error.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here, docker version, browser version if applicable to the problem. Too much info is better than too little.
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
@ -2,7 +2,7 @@
|
||||
|
||||
# Nginx Proxy Manager
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
|
17
doc/ADVANCED_NGINX.md
Normal file
17
doc/ADVANCED_NGINX.md
Normal file
@ -0,0 +1,17 @@
|
||||
## Advanced Nginx Configuration
|
||||
|
||||
If you are a more advanced user, you might be itching for extra Nginx customizability.
|
||||
|
||||
NPM has the ability to include different custom configuration snippets in different places.
|
||||
|
||||
You can add your custom configuration snippet files at `/data/nginx/custom` as follow:
|
||||
|
||||
`/data/nginx/custom/root.conf`: Included at the very end of nginx.conf
|
||||
`/data/nginx/custom/http.conf`: Included at the end of the main http block
|
||||
`/data/nginx/custom/server_proxy.conf`: Included at the end of every proxy server block
|
||||
`/data/nginx/custom/server_redirect.conf`: Included at the end of every redirection server block
|
||||
`/data/nginx/custom/server_stream.conf`: Included at the end of every stream server block
|
||||
`/data/nginx/custom/server_stream_tcp.conf`: Included at the end of every TCP stream server block
|
||||
`/data/nginx/custom/server_stream_udp.conf`: Included at the end of every UDP stream server block
|
||||
|
||||
Every file is optional.
|
@ -1,8 +1,8 @@
|
||||

|
||||
|
||||
# Nginx Proxy Manager
|
||||
# [Nginx Proxy Manager](https://nginxproxymanager.jc21.com)
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
@ -15,16 +15,18 @@ running at home or otherwise, including free SSL, without having to know too muc
|
||||
## Tags
|
||||
|
||||
* latest 2, 2.x.x ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/master/Dockerfile))
|
||||
* latest-armhf, 2-armhf, 2.x.x-armhf ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/master/Dockerfile.armhf))
|
||||
* latest-arm64, 2-arm64, 2.x.x-arm64 ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/master/Dockerfile.arm64))
|
||||
* 1, 1.x.x ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/1.1.2/Dockerfile))
|
||||
* 1-armhf, 1.x.x-armhf ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/1.1.2/Dockerfile.armhf))
|
||||
* latest-arm7l, 2-arm7l, 2.x.x-arm7l ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/master/Dockerfile.arm7l))
|
||||
|
||||
|
||||
## Getting started
|
||||
|
||||
Please consult the [installation instructions](https://github.com/jc21/nginx-proxy-manager/blob/master/doc/INSTALL.md) for a complete guide or
|
||||
if you just want to get up and running in the quickest time possible, grab all the files in the [doc/example/](https://github.com/jc21/nginx-proxy-manager/tree/master/doc/example) folder and run `docker-compose up -d`
|
||||
if you just want to get up and running in the quickest time possible, grab all the files in the [doc/example/](https://github.com/jc21/nginx-proxy-manager/tree/master/doc/example) folder and run:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
|
||||
## Screenshots
|
||||
|
112
doc/INSTALL.md
112
doc/INSTALL.md
@ -1,9 +1,13 @@
|
||||
## Installation and Configuration
|
||||
|
||||
There's a few ways to configure this app depending on:
|
||||
If you just want to get up and running in the quickest time possible, grab all the files in
|
||||
the [doc/example/](https://github.com/jc21/nginx-proxy-manager/tree/master/doc/example)
|
||||
folder and run:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
- Whether you use `docker-compose` or vanilla docker
|
||||
- Which architecture you're running it on (raspberry pi also supported - Testers wanted!)
|
||||
|
||||
### Configuration File
|
||||
|
||||
@ -13,22 +17,22 @@ Don't worry, this is easy to do.
|
||||
|
||||
The app requires a configuration file to let it know what database you're using.
|
||||
|
||||
Here's an example configuration for `mysql` (or mariadb):
|
||||
Here's an example configuration for `mysql` (or mariadb) that is compatible with the docker-compose example below:
|
||||
|
||||
```json
|
||||
{
|
||||
"database": {
|
||||
"engine": "mysql",
|
||||
"host": "127.0.0.1",
|
||||
"name": "nginxproxymanager",
|
||||
"user": "nginxproxymanager",
|
||||
"password": "password123",
|
||||
"host": "db",
|
||||
"name": "npm",
|
||||
"user": "npm",
|
||||
"password": "npm",
|
||||
"port": 3306
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Once you've created your configuration file it's easy to mount it in the docker container, examples below.
|
||||
Once you've created your configuration file it's easy to mount it in the docker container.
|
||||
|
||||
**Note:** After the first run of the application, the config file will be altered to include generated encryption keys unique to your installation. These keys
|
||||
affect the login and session management of the application. If these keys change for any reason, all users will be logged out.
|
||||
@ -36,37 +40,13 @@ affect the login and session management of the application. If these keys change
|
||||
|
||||
### Database
|
||||
|
||||
This app doesn't come with a database, you have to provide one yourself. Currently only `mysql/mariadb` is supported.
|
||||
This app doesn't come with a database, you have to provide one yourself. Currently only `mysql/mariadb` is supported for the minimum versions:
|
||||
|
||||
It's easy to use another docker container for your database also and link it as part of the docker stack. Here's an example:
|
||||
- MySQL v5.7.8+
|
||||
- MariaDB v10.2.7+
|
||||
|
||||
```yml
|
||||
version: "3"
|
||||
services:
|
||||
app:
|
||||
image: jc21/nginx-proxy-manager:latest
|
||||
restart: always
|
||||
ports:
|
||||
- 80:80
|
||||
- 81:81
|
||||
- 443:443
|
||||
volumes:
|
||||
- ./config.json:/app/config/production.json
|
||||
- ./data:/data
|
||||
- ./letsencrypt:/etc/letsencrypt
|
||||
depends_on:
|
||||
- db
|
||||
db:
|
||||
image: jc21/mariadb-aria
|
||||
restart: always
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: "password123"
|
||||
MYSQL_DATABASE: "nginxproxymanager"
|
||||
MYSQL_USER: "nginxproxymanager"
|
||||
MYSQL_PASSWORD: "password123"
|
||||
volumes:
|
||||
- ./data/mysql:/var/lib/mysql
|
||||
```
|
||||
It's easy to use another docker container for your database also and link it as part of the docker stack, so that's what the following examples
|
||||
are going to use.
|
||||
|
||||
|
||||
### Running the App
|
||||
@ -80,48 +60,51 @@ services:
|
||||
image: jc21/nginx-proxy-manager:latest
|
||||
restart: always
|
||||
ports:
|
||||
# Public HTTP Port:
|
||||
- 80:80
|
||||
- 81:81
|
||||
# Public HTTPS Port:
|
||||
- 443:443
|
||||
# Admin Web Port:
|
||||
- 81:81
|
||||
volumes:
|
||||
# Make sure this config.json file exists as per instructions above:
|
||||
- ./config.json:/app/config/production.json
|
||||
- ./data:/data
|
||||
- ./letsencrypt:/etc/letsencrypt
|
||||
depends_on:
|
||||
- db
|
||||
db:
|
||||
image: mariadb
|
||||
restart: always
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: "npm"
|
||||
MYSQL_DATABASE: "npm"
|
||||
MYSQL_USER: "npm"
|
||||
MYSQL_PASSWORD: "npm"
|
||||
volumes:
|
||||
- ./data/mysql:/var/lib/mysql
|
||||
```
|
||||
|
||||
Vanilla Docker:
|
||||
Then:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name nginx-proxy-manager \
|
||||
-p 80:80 \
|
||||
-p 81:81 \
|
||||
-p 443:443 \
|
||||
-v /path/to/config.json:/app/config/production.json \
|
||||
-v /path/to/data:/data \
|
||||
-v /path/to/letsencrypt:/etc/letsencrypt \
|
||||
jc21/nginx-proxy-manager:latest
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
|
||||
### Running on Raspberry PI / `armhf`
|
||||
### Running on Raspberry PI / ARM devices
|
||||
|
||||
I have created `armhf` and `arm64` docker containers just for you. There may be issues with it,
|
||||
if you have issues please report them here.
|
||||
There are docker images for all versions of the Rasberry Pi with the exception of the really old `armv6l` versions.
|
||||
|
||||
Note: Rpi v2 and below won't work with these images.
|
||||
The `latest` docker image is a manifest of all the different architecture docker builds supported, so this means
|
||||
you don't have to worry about doing anything special and you can follow the common instructions above.
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name nginx-proxy-manager-app \
|
||||
-p 80:80 \
|
||||
-p 81:81 \
|
||||
-p 443:443 \
|
||||
-v /path/to/config.json:/app/config/production.json \
|
||||
-v /path/to/data:/data \
|
||||
-v /path/to/letsencrypt:/etc/letsencrypt \
|
||||
jc21/nginx-proxy-manager:latest-armhf
|
||||
```
|
||||
Check out the [dockerhub tags](https://cloud.docker.com/repository/registry-1.docker.io/jc21/nginx-proxy-manager/tags)
|
||||
for a list of supported architectures and if you want one that doesn't exist,
|
||||
[create a feature request](https://github.com/jc21/nginx-proxy-manager/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=).
|
||||
|
||||
Also, if you don't know how to already, follow [this guide to install docker and docker-compose](https://manre-universe.net/how-to-run-docker-and-docker-compose-on-raspbian/)
|
||||
on Raspbian.
|
||||
|
||||
|
||||
### Initial Run
|
||||
@ -162,4 +145,3 @@ value by specifying it as a Docker environment variable. The default if not spec
|
||||
```
|
||||
... -e "X_FRAME_OPTIONS=sameorigin" ...
|
||||
```
|
||||
|
||||
|
@ -2,9 +2,9 @@
|
||||
"database": {
|
||||
"engine": "mysql",
|
||||
"host": "db",
|
||||
"name": "nginxproxymanager",
|
||||
"user": "nginxproxymanager",
|
||||
"password": "password123",
|
||||
"name": "npm",
|
||||
"user": "npm",
|
||||
"password": "npm",
|
||||
"port": 3306
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
version: "3"
|
||||
services:
|
||||
app:
|
||||
image: jc21/nginx-proxy-manager:2
|
||||
image: jc21/nginx-proxy-manager:latest
|
||||
restart: always
|
||||
ports:
|
||||
- 80:80
|
||||
@ -17,12 +17,12 @@ services:
|
||||
# if you want pretty colors in your docker logs:
|
||||
- FORCE_COLOR=1
|
||||
db:
|
||||
image: jc21/mariadb-aria
|
||||
image: mariadb:latest
|
||||
restart: always
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: "password123"
|
||||
MYSQL_DATABASE: "nginxproxymanager"
|
||||
MYSQL_USER: "nginxproxymanager"
|
||||
MYSQL_PASSWORD: "password123"
|
||||
MYSQL_ROOT_PASSWORD: "npm"
|
||||
MYSQL_DATABASE: "npm"
|
||||
MYSQL_USER: "npm"
|
||||
MYSQL_PASSWORD: "npm"
|
||||
volumes:
|
||||
- ./data/mysql:/var/lib/mysql
|
||||
|
@ -4,9 +4,9 @@ services:
|
||||
app:
|
||||
image: jc21/nginx-proxy-manager-base:latest
|
||||
ports:
|
||||
- 8080:80
|
||||
- 8081:81
|
||||
- 8443:443
|
||||
- 80:80
|
||||
- 81:81
|
||||
- 43:443
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
- FORCE_COLOR=1
|
||||
@ -22,7 +22,7 @@ services:
|
||||
- db
|
||||
command: node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js
|
||||
db:
|
||||
image: mariadb:10.3.7
|
||||
image: jc21/mariadb-aria
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: "npm"
|
||||
MYSQL_DATABASE: "npm"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "nginx-proxy-manager",
|
||||
"version": "2.0.12",
|
||||
"version": "2.0.14",
|
||||
"description": "A beautiful interface for creating Nginx endpoints",
|
||||
"main": "src/backend/index.js",
|
||||
"devDependencies": {
|
||||
@ -28,7 +28,7 @@
|
||||
"numeral": "^2.0.6",
|
||||
"sass-loader": "^7.0.3",
|
||||
"style-loader": "^0.22.1",
|
||||
"tabler-ui": "git+https://github.com/tabler/tabler.git",
|
||||
"tabler-ui": "git+https://github.com/tabler/tabler.git#00f78ad823311bc3ad974ac3e5b0126198f0a813",
|
||||
"underscore": "^1.8.3",
|
||||
"webpack": "^4.25.1",
|
||||
"webpack-cli": "^3.1.2",
|
||||
|
@ -47,7 +47,7 @@ server {
|
||||
|
||||
ssl_certificate /data/nginx/dummycert.pem;
|
||||
ssl_certificate_key /data/nginx/dummykey.pem;
|
||||
ssl_ciphers aNULL;
|
||||
include conf.d/include/ssl-ciphers.conf;
|
||||
|
||||
return 444;
|
||||
}
|
||||
|
@ -2,7 +2,10 @@
|
||||
# We use ^~ here, so that we don't check other regexes (for speed-up). We actually MUST cancel
|
||||
# other regex checks, because in our other config files have regex rule that denies access to files with dotted names.
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
# Since this is for letsencrypt authentication of a domain and they do not give IP ranges of their infrastructure
|
||||
# we need to open up access by turning off auth and IP ACL for this location.
|
||||
auth_basic off;
|
||||
allow all;
|
||||
|
||||
# Set correct content type. According to this:
|
||||
# https://community.letsencrypt.org/t/using-the-webroot-domain-verification-method/1445/29
|
||||
|
@ -2,8 +2,8 @@ ssl_session_timeout 5m;
|
||||
ssl_session_cache shared:SSL:50m;
|
||||
|
||||
# intermediate configuration. tweak to your needs.
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers 'EECDH+AESGCM:AES256+EECDH:AES256+EDH:EDH+AESGCM:ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-
|
||||
ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AE
|
||||
S128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
|
||||
S128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES';
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
@ -76,6 +76,9 @@ http {
|
||||
include /data/nginx/redirection_host/*.conf;
|
||||
include /data/nginx/dead_host/*.conf;
|
||||
include /data/nginx/temp/*.conf;
|
||||
|
||||
# Custom
|
||||
include /data/nginx/custom/http[.]conf;
|
||||
}
|
||||
|
||||
stream {
|
||||
@ -83,3 +86,5 @@ stream {
|
||||
include /data/nginx/stream/*.conf;
|
||||
}
|
||||
|
||||
# Custom
|
||||
include /data/nginx/custom/root[.]conf;
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
@ -48,7 +46,7 @@ app.use(function (req, res, next) {
|
||||
|
||||
res.set({
|
||||
'Strict-Transport-Security': 'includeSubDomains; max-age=631138519; preload',
|
||||
'X-XSS-Protection': '0',
|
||||
'X-XSS-Protection': '1; mode=block',
|
||||
'X-Content-Type-Options': 'nosniff',
|
||||
'X-Frame-Options': x_frame_options,
|
||||
'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const config = require('config');
|
||||
|
||||
if (!config.has('database')) {
|
||||
|
@ -1,10 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const logger = require('./logger').import;
|
||||
const utils = require('./lib/utils');
|
||||
const batchflow = require('batchflow');
|
||||
const debug_mode = process.env.NODE_ENV !== 'production';
|
||||
const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG;
|
||||
|
||||
const internalProxyHost = require('./internal/proxy-host');
|
||||
const internalRedirectionHost = require('./internal/redirection-host');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const fs = require('fs');
|
||||
const batchflow = require('batchflow');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const error = require('../lib/error');
|
||||
const auditLogModel = require('../models/audit-log');
|
||||
|
||||
@ -46,9 +44,9 @@ const internalAuditLog = {
|
||||
* @param {Access} access
|
||||
* @param {Object} data
|
||||
* @param {String} data.action
|
||||
* @param {Integer} [data.user_id]
|
||||
* @param {Integer} [data.object_id]
|
||||
* @param {Integer} [data.object_type]
|
||||
* @param {Number} [data.user_id]
|
||||
* @param {Number} [data.object_id]
|
||||
* @param {Number} [data.object_type]
|
||||
* @param {Object} [data.meta]
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const _ = require('lodash');
|
||||
const logger = require('../logger').ssl;
|
||||
@ -9,7 +7,8 @@ const internalAuditLog = require('./audit-log');
|
||||
const tempWrite = require('temp-write');
|
||||
const utils = require('../lib/utils');
|
||||
const moment = require('moment');
|
||||
const debug_mode = process.env.NODE_ENV !== 'production';
|
||||
const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG;
|
||||
const le_staging = process.env.NODE_ENV !== 'production';
|
||||
const internalNginx = require('./nginx');
|
||||
const internalHost = require('./host');
|
||||
const certbot_command = '/usr/bin/certbot';
|
||||
@ -21,7 +20,7 @@ function omissions () {
|
||||
const internalCertificate = {
|
||||
|
||||
allowed_ssl_files: ['certificate', 'certificate_key', 'intermediate_certificate'],
|
||||
interval_timeout: 1000 * 60 * 60 * 12, // 12 hours
|
||||
interval_timeout: 1000 * 60 * 60, // 1 hour
|
||||
interval: null,
|
||||
interval_processing: false,
|
||||
|
||||
@ -38,7 +37,7 @@ const internalCertificate = {
|
||||
internalCertificate.interval_processing = true;
|
||||
logger.info('Renewing SSL certs close to expiry...');
|
||||
|
||||
return utils.exec(certbot_command + ' renew -q ' + (debug_mode ? '--staging' : ''))
|
||||
return utils.exec(certbot_command + ' renew -q ' + (le_staging ? '--staging' : ''))
|
||||
.then(result => {
|
||||
logger.info(result);
|
||||
|
||||
@ -205,7 +204,7 @@ const internalCertificate = {
|
||||
/**
|
||||
* @param {Access} access
|
||||
* @param {Object} data
|
||||
* @param {Integer} data.id
|
||||
* @param {Number} data.id
|
||||
* @param {String} [data.email]
|
||||
* @param {String} [data.name]
|
||||
* @return {Promise}
|
||||
@ -251,7 +250,7 @@ const internalCertificate = {
|
||||
/**
|
||||
* @param {Access} access
|
||||
* @param {Object} data
|
||||
* @param {Integer} data.id
|
||||
* @param {Number} data.id
|
||||
* @param {Array} [data.expand]
|
||||
* @param {Array} [data.omit]
|
||||
* @return {Promise}
|
||||
@ -297,7 +296,7 @@ const internalCertificate = {
|
||||
/**
|
||||
* @param {Access} access
|
||||
* @param {Object} data
|
||||
* @param {Integer} data.id
|
||||
* @param {Number} data.id
|
||||
* @param {String} [data.reason]
|
||||
* @returns {Promise}
|
||||
*/
|
||||
@ -381,7 +380,7 @@ const internalCertificate = {
|
||||
/**
|
||||
* Report use
|
||||
*
|
||||
* @param {Integer} user_id
|
||||
* @param {Number} user_id
|
||||
* @param {String} visibility
|
||||
* @returns {Promise}
|
||||
*/
|
||||
@ -522,7 +521,7 @@ const internalCertificate = {
|
||||
/**
|
||||
* @param {Access} access
|
||||
* @param {Object} data
|
||||
* @param {Integer} data.id
|
||||
* @param {Number} data.id
|
||||
* @param {Object} data.files
|
||||
* @returns {Promise}
|
||||
*/
|
||||
@ -719,9 +718,9 @@ const internalCertificate = {
|
||||
|
||||
let cmd = certbot_command + ' certonly --cert-name "npm-' + certificate.id + '" --agree-tos ' +
|
||||
'--email "' + certificate.meta.letsencrypt_email + '" ' +
|
||||
'--preferred-challenges "http" ' +
|
||||
'--preferred-challenges "dns,http" ' +
|
||||
'-n -a webroot -d "' + certificate.domain_names.join(',') + '" ' +
|
||||
(debug_mode ? '--staging' : '');
|
||||
(le_staging ? '--staging' : '');
|
||||
|
||||
if (debug_mode) {
|
||||
logger.info('Command:', cmd);
|
||||
@ -734,6 +733,48 @@ const internalCertificate = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Access} access
|
||||
* @param {Object} data
|
||||
* @param {Number} data.id
|
||||
* @returns {Promise}
|
||||
*/
|
||||
renew: (access, data) => {
|
||||
return access.can('certificates:update', data)
|
||||
.then(() => {
|
||||
return internalCertificate.get(access, data);
|
||||
})
|
||||
.then((certificate) => {
|
||||
if (certificate.provider === 'letsencrypt') {
|
||||
return internalCertificate.renewLetsEncryptSsl(certificate)
|
||||
.then(() => {
|
||||
return internalCertificate.getCertificateInfoFromFile('/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem')
|
||||
})
|
||||
.then(cert_info => {
|
||||
return certificateModel
|
||||
.query()
|
||||
.patchAndFetchById(certificate.id, {
|
||||
expires_on: certificateModel.raw('FROM_UNIXTIME(' + cert_info.dates.to + ')')
|
||||
});
|
||||
})
|
||||
.then((updated_certificate) => {
|
||||
// Add to audit log
|
||||
return internalAuditLog.add(access, {
|
||||
action: 'renewed',
|
||||
object_type: 'certificate',
|
||||
object_id: updated_certificate.id,
|
||||
meta: updated_certificate
|
||||
})
|
||||
.then(() => {
|
||||
return updated_certificate;
|
||||
});
|
||||
})
|
||||
} else {
|
||||
throw new error.ValidationError('Only Let\'sEncrypt certificates can be renewed');
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Object} certificate the certificate row
|
||||
* @returns {Promise}
|
||||
@ -741,7 +782,7 @@ const internalCertificate = {
|
||||
renewLetsEncryptSsl: certificate => {
|
||||
logger.info('Renewing Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
||||
|
||||
let cmd = certbot_command + ' renew -n --force-renewal --disable-hook-validation --cert-name "npm-' + certificate.id + '" ' + (debug_mode ? '--staging' : '');
|
||||
let cmd = certbot_command + ' renew -n --force-renewal --disable-hook-validation --cert-name "npm-' + certificate.id + '" ' + (le_staging ? '--staging' : '');
|
||||
|
||||
if (debug_mode) {
|
||||
logger.info('Command:', cmd);
|
||||
@ -762,17 +803,29 @@ const internalCertificate = {
|
||||
revokeLetsEncryptSsl: (certificate, throw_errors) => {
|
||||
logger.info('Revoking Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
||||
|
||||
let cmd = certbot_command + ' revoke --cert-path "/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' + (debug_mode ? '--staging' : '');
|
||||
let revoke_cmd = certbot_command + ' revoke --cert-path "/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' + (le_staging ? '--staging' : '');
|
||||
let delete_cmd = certbot_command + ' delete --cert-name "npm-' + certificate.id + '" ' + (le_staging ? '--staging' : '');
|
||||
|
||||
if (debug_mode) {
|
||||
logger.info('Command:', cmd);
|
||||
logger.info('Command:', revoke_cmd);
|
||||
}
|
||||
|
||||
return utils.exec(cmd)
|
||||
.then(result => {
|
||||
return utils.exec(revoke_cmd)
|
||||
.then((result) => {
|
||||
logger.info(result);
|
||||
return result;
|
||||
})
|
||||
.then(() => {
|
||||
if (debug_mode) {
|
||||
logger.info('Command:', delete_cmd);
|
||||
}
|
||||
|
||||
return utils.exec(delete_cmd)
|
||||
.then((result) => {
|
||||
logger.info(result);
|
||||
return result;
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
if (debug_mode) {
|
||||
logger.error(err.message);
|
||||
@ -796,7 +849,7 @@ const internalCertificate = {
|
||||
|
||||
/**
|
||||
* @param {Object} in_use_result
|
||||
* @param {Integer} in_use_result.total_count
|
||||
* @param {Number} in_use_result.total_count
|
||||
* @param {Array} in_use_result.proxy_hosts
|
||||
* @param {Array} in_use_result.redirection_hosts
|
||||
* @param {Array} in_use_result.dead_hosts
|
||||
@ -826,7 +879,7 @@ const internalCertificate = {
|
||||
|
||||
/**
|
||||
* @param {Object} in_use_result
|
||||
* @param {Integer} in_use_result.total_count
|
||||
* @param {Number} in_use_result.total_count
|
||||
* @param {Array} in_use_result.proxy_hosts
|
||||
* @param {Array} in_use_result.redirection_hosts
|
||||
* @param {Array} in_use_result.dead_hosts
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const error = require('../lib/error');
|
||||
const deadHostModel = require('../models/dead_host');
|
||||
|
@ -1,8 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const https = require('https');
|
||||
const fs = require('fs');
|
||||
const _ = require('lodash');
|
||||
const logger = require('../logger').ip_ranges;
|
||||
const error = require('../lib/error');
|
||||
const internalNginx = require('./nginx');
|
||||
|
@ -4,7 +4,7 @@ const Liquid = require('liquidjs');
|
||||
const logger = require('../logger').nginx;
|
||||
const utils = require('../lib/utils');
|
||||
const error = require('../lib/error');
|
||||
const debug_mode = process.env.NODE_ENV !== 'production';
|
||||
const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG;
|
||||
|
||||
const internalNginx = {
|
||||
|
||||
@ -162,7 +162,7 @@ const internalNginx = {
|
||||
|
||||
renderedLocations += await renderer.parseAndRender(template, locationCopy);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
locationRendering().then(() => resolve(renderedLocations));
|
||||
});
|
||||
@ -211,6 +211,14 @@ const internalNginx = {
|
||||
locationsPromise = internalNginx.renderLocations(host).then((renderedLocations) => {
|
||||
host.locations = renderedLocations;
|
||||
});
|
||||
|
||||
// Allow someone who is using / custom location path to use it, and skip the default / location
|
||||
_.map(host.locations, (location) => {
|
||||
if (location.path === '/') {
|
||||
host.use_default_location = false;
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
locationsPromise = Promise.resolve();
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ const internalProxyHost = {
|
||||
}
|
||||
|
||||
return access.can('proxy_hosts:create', data)
|
||||
.then(access_data => {
|
||||
.then(() => {
|
||||
// Get a list of the domain names and check each of them against existing records
|
||||
let domain_name_check_promises = [];
|
||||
|
||||
@ -52,7 +52,7 @@ const internalProxyHost = {
|
||||
.omit(omissions())
|
||||
.insertAndFetch(data);
|
||||
})
|
||||
.then(row => {
|
||||
.then((row) => {
|
||||
if (create_certificate) {
|
||||
return internalCertificate.createQuickCertificate(access, data)
|
||||
.then(cert => {
|
||||
@ -69,21 +69,21 @@ const internalProxyHost = {
|
||||
return row;
|
||||
}
|
||||
})
|
||||
.then(row => {
|
||||
.then((row) => {
|
||||
// re-fetch with cert
|
||||
return internalProxyHost.get(access, {
|
||||
id: row.id,
|
||||
expand: ['certificate', 'owner', 'access_list']
|
||||
});
|
||||
})
|
||||
.then(row => {
|
||||
.then((row) => {
|
||||
// Configure nginx
|
||||
return internalNginx.configure(proxyHostModel, 'proxy_host', row)
|
||||
.then(() => {
|
||||
return row;
|
||||
});
|
||||
})
|
||||
.then(row => {
|
||||
.then((row) => {
|
||||
// Audit log
|
||||
data.meta = _.assign({}, data.meta || {}, row.meta);
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const error = require('../lib/error');
|
||||
const redirectionHostModel = require('../models/redirection_host');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const internalProxyHost = require('./proxy-host');
|
||||
const internalRedirectionHost = require('./redirection-host');
|
||||
const internalDeadHost = require('./dead-host');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const error = require('../lib/error');
|
||||
const streamModel = require('../models/stream');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const error = require('../lib/error');
|
||||
const userModel = require('../models/user');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const error = require('../lib/error');
|
||||
const userModel = require('../models/user');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Some Notes: This is a friggin complicated piece of code.
|
||||
*
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const util = require('util');
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const validator = require('../validator');
|
||||
|
||||
module.exports = function (req, res, next) {
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Access = require('../access');
|
||||
|
||||
module.exports = () => {
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function () {
|
||||
return function (req, res, next) {
|
||||
if (req.headers.authorization) {
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
let _ = require('lodash');
|
||||
|
||||
module.exports = function (default_sort, default_offset, default_limit, max_limit) {
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = (req, res, next) => {
|
||||
if (req.params.user_id === 'me' && res.locals.access) {
|
||||
req.params.user_id = res.locals.access.token.get('attrs').id;
|
||||
|
@ -1,7 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const moment = require('moment');
|
||||
const _ = require('lodash');
|
||||
|
||||
module.exports = {
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const migrate_name = 'identifier_for_migrate';
|
||||
const logger = require('../logger').migrate;
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const exec = require('child_process').exec;
|
||||
|
||||
module.exports = {
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const error = require('../error');
|
||||
const path = require('path');
|
||||
const parser = require('json-schema-ref-parser');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const error = require('../error');
|
||||
const definitions = require('../../schema/definitions.json');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const db = require('./db');
|
||||
const logger = require('./logger').migrate;
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const migrate_name = 'initial-schema';
|
||||
const logger = require('../logger').migrate;
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const migrate_name = 'websockets';
|
||||
const logger = require('../logger').migrate;
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const migrate_name = 'forward_host';
|
||||
const logger = require('../logger').migrate;
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const migrate_name = 'http2_support';
|
||||
const logger = require('../logger').migrate;
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const migrate_name = 'forward_scheme';
|
||||
const logger = require('../logger').migrate;
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const migrate_name = 'disabled';
|
||||
const logger = require('../logger').migrate;
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const migrate_name = 'custom_locations';
|
||||
const logger = require('../logger').migrate;
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const migrate_name = 'hsts';
|
||||
const logger = require('../logger').migrate;
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Objection Docs:
|
||||
// http://vincit.github.io/objection.js/
|
||||
|
||||
'use strict';
|
||||
|
||||
const db = require('../db');
|
||||
const Model = require('objection').Model;
|
||||
const User = require('./user');
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Objection Docs:
|
||||
// http://vincit.github.io/objection.js/
|
||||
|
||||
'use strict';
|
||||
|
||||
const db = require('../db');
|
||||
const Model = require('objection').Model;
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Objection Docs:
|
||||
// http://vincit.github.io/objection.js/
|
||||
|
||||
'use strict';
|
||||
|
||||
const db = require('../db');
|
||||
const Model = require('objection').Model;
|
||||
const User = require('./user');
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Objection Docs:
|
||||
// http://vincit.github.io/objection.js/
|
||||
|
||||
'use strict';
|
||||
|
||||
const bcrypt = require('bcrypt');
|
||||
const db = require('../db');
|
||||
const Model = require('objection').Model;
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Objection Docs:
|
||||
// http://vincit.github.io/objection.js/
|
||||
|
||||
'use strict';
|
||||
|
||||
const db = require('../db');
|
||||
const Model = require('objection').Model;
|
||||
const User = require('./user');
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Objection Docs:
|
||||
// http://vincit.github.io/objection.js/
|
||||
|
||||
'use strict';
|
||||
|
||||
const db = require('../db');
|
||||
const Model = require('objection').Model;
|
||||
const User = require('./user');
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Objection Docs:
|
||||
// http://vincit.github.io/objection.js/
|
||||
|
||||
'use strict';
|
||||
|
||||
const db = require('../db');
|
||||
const Model = require('objection').Model;
|
||||
const User = require('./user');
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Objection Docs:
|
||||
// http://vincit.github.io/objection.js/
|
||||
|
||||
'use strict';
|
||||
|
||||
const db = require('../db');
|
||||
const Model = require('objection').Model;
|
||||
const User = require('./user');
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Objection Docs:
|
||||
// http://vincit.github.io/objection.js/
|
||||
|
||||
'use strict';
|
||||
|
||||
const db = require('../db');
|
||||
const Model = require('objection').Model;
|
||||
const User = require('./user');
|
||||
|
@ -3,8 +3,6 @@
|
||||
and then has abilities after that.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const config = require('config');
|
||||
const jwt = require('jsonwebtoken');
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Objection Docs:
|
||||
// http://vincit.github.io/objection.js/
|
||||
|
||||
'use strict';
|
||||
|
||||
const db = require('../db');
|
||||
const Model = require('objection').Model;
|
||||
const UserPermission = require('./user_permission');
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Objection Docs:
|
||||
// http://vincit.github.io/objection.js/
|
||||
|
||||
'use strict';
|
||||
|
||||
const db = require('../db');
|
||||
const Model = require('objection').Model;
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const express = require('express');
|
||||
const validator = require('../../lib/validator');
|
||||
const jwtdecode = require('../../lib/express/jwt-decode');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const express = require('express');
|
||||
const pjson = require('../../../../package.json');
|
||||
const error = require('../../lib/error');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const express = require('express');
|
||||
const validator = require('../../../lib/validator');
|
||||
const jwtdecode = require('../../../lib/express/jwt-decode');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const express = require('express');
|
||||
const validator = require('../../../lib/validator');
|
||||
const jwtdecode = require('../../../lib/express/jwt-decode');
|
||||
@ -181,6 +179,34 @@ router
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Renew LE Certs
|
||||
*
|
||||
* /api/nginx/certificates/123/renew
|
||||
*/
|
||||
router
|
||||
.route('/:certificate_id/renew')
|
||||
.options((req, res) => {
|
||||
res.sendStatus(204);
|
||||
})
|
||||
.all(jwtdecode())
|
||||
|
||||
/**
|
||||
* POST /api/nginx/certificates/123/renew
|
||||
*
|
||||
* Renew certificate
|
||||
*/
|
||||
.post((req, res, next) => {
|
||||
internalCertificate.renew(res.locals.access, {
|
||||
id: parseInt(req.params.certificate_id, 10)
|
||||
})
|
||||
.then(result => {
|
||||
res.status(200)
|
||||
.send(result);
|
||||
})
|
||||
.catch(next);
|
||||
});
|
||||
|
||||
/**
|
||||
* Validate Certs before saving
|
||||
*
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const express = require('express');
|
||||
const validator = require('../../../lib/validator');
|
||||
const jwtdecode = require('../../../lib/express/jwt-decode');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const express = require('express');
|
||||
const validator = require('../../../lib/validator');
|
||||
const jwtdecode = require('../../../lib/express/jwt-decode');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const express = require('express');
|
||||
const validator = require('../../../lib/validator');
|
||||
const jwtdecode = require('../../../lib/express/jwt-decode');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const express = require('express');
|
||||
const validator = require('../../../lib/validator');
|
||||
const jwtdecode = require('../../../lib/express/jwt-decode');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const express = require('express');
|
||||
const jwtdecode = require('../../lib/express/jwt-decode');
|
||||
const internalReport = require('../../internal/report');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const express = require('express');
|
||||
const jwtdecode = require('../../lib/express/jwt-decode');
|
||||
const internalToken = require('../../internal/token');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const express = require('express');
|
||||
const validator = require('../../lib/validator');
|
||||
const jwtdecode = require('../../lib/express/jwt-decode');
|
||||
|
@ -1,8 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const express = require('express');
|
||||
const fs = require('fs');
|
||||
const PACKAGE = require('../../../package.json');
|
||||
const path = require('path')
|
||||
|
||||
const router = express.Router({
|
||||
caseSensitive: true,
|
||||
@ -29,7 +28,9 @@ router.get(/(.*)/, function (req, res, next) {
|
||||
version: PACKAGE.version
|
||||
});
|
||||
} else {
|
||||
fs.readFile('dist' + req.params.page, 'utf8', function (err, data) {
|
||||
var p = path.normalize('dist' + req.params.page)
|
||||
if (p.startsWith('dist')) { // Allow access to ressources under 'dist' directory only.
|
||||
fs.readFile(p, 'utf8', function (err, data) {
|
||||
if (err) {
|
||||
res.render('index', {
|
||||
version: PACKAGE.version
|
||||
@ -38,6 +39,11 @@ router.get(/(.*)/, function (req, res, next) {
|
||||
res.contentType('text/html').end(data);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.render('index', {
|
||||
version: PACKAGE.version
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const NodeRSA = require('node-rsa');
|
||||
const config = require('config');
|
||||
@ -7,7 +5,7 @@ const logger = require('./logger').setup;
|
||||
const userModel = require('./models/user');
|
||||
const userPermissionModel = require('./models/user_permission');
|
||||
const authModel = require('./models/auth');
|
||||
const debug_mode = process.env.NODE_ENV !== 'production';
|
||||
const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG;
|
||||
|
||||
module.exports = function () {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -41,5 +41,7 @@ server {
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
# Custom
|
||||
include /data/nginx/custom/server_proxy[.]conf;
|
||||
}
|
||||
{% endif %}
|
||||
|
@ -25,5 +25,7 @@ server {
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
# Custom
|
||||
include /data/nginx/custom/server_redirect[.]conf;
|
||||
}
|
||||
{% endif %}
|
||||
|
@ -7,12 +7,20 @@
|
||||
server {
|
||||
listen {{ incoming_port }};
|
||||
proxy_pass {{ forward_ip }}:{{ forwarding_port }};
|
||||
|
||||
# Custom
|
||||
include /data/nginx/custom/server_stream[.]conf;
|
||||
include /data/nginx/custom/server_stream_tcp[.]conf;
|
||||
}
|
||||
{% endif %}
|
||||
{% if udp_forwarding == 1 or udp_forwarding == true %}
|
||||
server {
|
||||
listen {{ incoming_port }} udp;
|
||||
proxy_pass {{ forward_ip }}:{{ forwarding_port }};
|
||||
|
||||
# Custom
|
||||
include /data/nginx/custom/server_stream[.]conf;
|
||||
include /data/nginx/custom/server_stream_udp[.]conf;
|
||||
}
|
||||
{% endif %}
|
||||
{% endif %}
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const $ = require('jquery');
|
||||
const _ = require('underscore');
|
||||
const Tokens = require('./tokens');
|
||||
@ -55,7 +53,7 @@ function fetch (verb, path, data, options) {
|
||||
contentType: options.contentType || 'application/json; charset=UTF-8',
|
||||
processData: options.processData || true,
|
||||
crossDomain: true,
|
||||
timeout: options.timeout ? options.timeout : 15000,
|
||||
timeout: options.timeout ? options.timeout : 30000,
|
||||
xhrFields: {
|
||||
withCredentials: true
|
||||
},
|
||||
@ -128,19 +126,6 @@ function getAllObjects (path, expand, query) {
|
||||
return fetch('get', path + (params.length ? '?' + params.join('&') : ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} path
|
||||
* @param {FormData} form_data
|
||||
* @returns {Promise}
|
||||
*/
|
||||
function upload (path, form_data) {
|
||||
console.log('UPLOAD:', path, form_data);
|
||||
return fetch('post', path, form_data, {
|
||||
contentType: 'multipart/form-data',
|
||||
processData: false
|
||||
});
|
||||
}
|
||||
|
||||
function FileUpload(path, fd) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let xhr = new XMLHttpRequest();
|
||||
@ -214,7 +199,7 @@ module.exports = {
|
||||
Users: {
|
||||
|
||||
/**
|
||||
* @param {Integer|String} user_id
|
||||
* @param {Number|String} user_id
|
||||
* @param {Array} [expand]
|
||||
* @returns {Promise}
|
||||
*/
|
||||
@ -639,6 +624,14 @@ module.exports = {
|
||||
*/
|
||||
validate: function (form_data) {
|
||||
return FileUpload('nginx/certificates/validate', form_data);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Number} id
|
||||
* @returns {Promise}
|
||||
*/
|
||||
renew: function (id) {
|
||||
return fetch('post', 'nginx/certificates/' + id + '/renew');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const Controller = require('../../controller');
|
||||
const template = require('./item.ejs');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const ItemView = require('./item');
|
||||
const template = require('./main.ejs');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const App = require('../main');
|
||||
const AuditLogModel = require('../../models/audit-log');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const template = require('./meta.ejs');
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const UserModel = require('../models/user');
|
||||
|
||||
let cache = {
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Backbone = require('backbone');
|
||||
const Cache = require('./cache');
|
||||
const Tokens = require('./tokens');
|
||||
@ -342,6 +340,19 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Certificate Renew
|
||||
*
|
||||
* @param model
|
||||
*/
|
||||
showNginxCertificateRenew: function (model) {
|
||||
if (Cache.User.isAdmin() || Cache.User.canManage('certificates')) {
|
||||
require(['./main', './nginx/certificates/renew'], function (App, View) {
|
||||
App.UI.showModalDialog(new View({model: model}));
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Certificate Delete Confirm
|
||||
*
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const Cache = require('../cache');
|
||||
const Controller = require('../controller');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const template = require('./main.ejs');
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const template = require('./main.ejs');
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const template = require('./main.ejs');
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Cache = ('./cache');
|
||||
const messages = require('../i18n/messages.json');
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('underscore');
|
||||
const Backbone = require('backbone');
|
||||
const Mn = require('../lib/marionette');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const App = require('../../main');
|
||||
const template = require('./delete.ejs');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const App = require('../../main');
|
||||
const AccessListModel = require('../../../models/access-list');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const template = require('./item.ejs');
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const App = require('../../../main');
|
||||
const template = require('./item.ejs');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const App = require('../../../main');
|
||||
const ItemView = require('./item');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const App = require('../../main');
|
||||
const AccessListModel = require('../../../models/access-list');
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const Mn = require('backbone.marionette');
|
||||
const App = require('../../main');
|
||||
const template = require('./delete.ejs');
|
||||
@ -16,7 +14,6 @@ module.exports = Mn.View.extend({
|
||||
},
|
||||
|
||||
events: {
|
||||
|
||||
'click @ui.save': function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('underscore');
|
||||
const Mn = require('backbone.marionette');
|
||||
const App = require('../../main');
|
||||
|
@ -4,17 +4,24 @@
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>
|
||||
<% if (provider === 'letsencrypt') { %>
|
||||
<% domain_names.map(function(host) {
|
||||
<div class="wrap">
|
||||
<%
|
||||
if (provider === 'letsencrypt') {
|
||||
domain_names.map(function(host) {
|
||||
if (host.indexOf('*') === -1) {
|
||||
%>
|
||||
<span class="tag host-link hover-pink" rel="https://<%- host %>"><%- host %></span>
|
||||
<%
|
||||
} else {
|
||||
%>
|
||||
<span class="tag"><%- host %></span>
|
||||
<%
|
||||
}
|
||||
});
|
||||
} else {
|
||||
%><%- nice_name %><%
|
||||
}
|
||||
%>
|
||||
<% } else { %>
|
||||
<%- nice_name %>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="small text-muted">
|
||||
<%- i18n('str', 'created-on', {date: formatDbDate(created_on, 'Do MMMM YYYY')}) %>
|
||||
@ -31,6 +38,10 @@
|
||||
<div class="item-action dropdown">
|
||||
<a href="#" data-toggle="dropdown" class="icon"><i class="fe fe-more-vertical"></i></a>
|
||||
<div class="dropdown-menu dropdown-menu-right">
|
||||
<% if (provider === 'letsencrypt') { %>
|
||||
<a href="#" class="renew dropdown-item"><i class="dropdown-icon fe fe-refresh-cw"></i> <%- i18n('certificates', 'force-renew') %></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>
|
||||
</div>
|
||||
</div>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user