Compare commits
58 Commits
Author | SHA1 | Date | |
---|---|---|---|
9fcd32c2ca | |||
2657bcf30c | |||
86ad7d6238 | |||
c97e6ada5b | |||
cd40ca7f0a | |||
e2ac3b4880 | |||
7f8b185e48 | |||
e923db7e94 | |||
e53d9fa3eb | |||
411734f392 | |||
a457a40359 | |||
caa183c8de | |||
0ea5014edb | |||
046cb0b76e | |||
9fd480cf77 | |||
0f94e68dca | |||
c15edf318d | |||
a73cbc7116 | |||
f9876326c9 | |||
7d5ca84501 | |||
0335370cfb | |||
9b852f01e3 | |||
20fd185652 | |||
ad41986bd5 | |||
c826ed8c1f | |||
eaebc48f66 | |||
eb391959aa | |||
dba4340548 | |||
0b8a49469f | |||
b16a68052f | |||
83686c4535 | |||
efa1424cad | |||
4fe26ec4c0 | |||
a72811ee25 | |||
ac9d9cdddd | |||
5ac0e3dc95 | |||
bbe02bc70a | |||
02b4def04a | |||
5dd723a864 | |||
d04f5a619a | |||
6542f4c2fe | |||
32d6bf83c8 | |||
a4b918e648 | |||
de367ae194 | |||
2226359cfe | |||
10e87d2e6f | |||
5b58fb3bd2 | |||
968750a856 | |||
673cfb0027 | |||
5b45312f17 | |||
95d9e87f51 | |||
1382350d3a | |||
353eeaa0ae | |||
3dee0eba4e | |||
2111d2913b | |||
36b014aa47 | |||
e2c6aedbfa | |||
cb449a8f5d |
@ -29,4 +29,11 @@ ADD knexfile.js /app/knexfile.js
|
|||||||
VOLUME [ "/data", "/etc/letsencrypt" ]
|
VOLUME [ "/data", "/etc/letsencrypt" ]
|
||||||
CMD [ "/init" ]
|
CMD [ "/init" ]
|
||||||
|
|
||||||
|
# Ports
|
||||||
|
EXPOSE 80
|
||||||
|
EXPOSE 81
|
||||||
|
EXPOSE 443
|
||||||
|
EXPOSE 9876
|
||||||
|
|
||||||
HEALTHCHECK --interval=15s --timeout=3s CMD curl -f http://localhost:9876/health || exit 1
|
HEALTHCHECK --interval=15s --timeout=3s CMD curl -f http://localhost:9876/health || exit 1
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM jc21/nginx-proxy-manager-base:armhf
|
FROM jc21/nginx-proxy-manager-base:latest-armhf
|
||||||
|
|
||||||
MAINTAINER Jamie Curnow <jc@jc21.com>
|
MAINTAINER Jamie Curnow <jc@jc21.com>
|
||||||
LABEL maintainer="Jamie Curnow <jc@jc21.com>"
|
LABEL maintainer="Jamie Curnow <jc@jc21.com>"
|
||||||
@ -29,4 +29,10 @@ ADD knexfile.js /app/knexfile.js
|
|||||||
VOLUME [ "/data", "/etc/letsencrypt" ]
|
VOLUME [ "/data", "/etc/letsencrypt" ]
|
||||||
CMD [ "/init" ]
|
CMD [ "/init" ]
|
||||||
|
|
||||||
|
# Ports
|
||||||
|
EXPOSE 80
|
||||||
|
EXPOSE 81
|
||||||
|
EXPOSE 443
|
||||||
|
EXPOSE 9876
|
||||||
|
|
||||||
HEALTHCHECK --interval=15s --timeout=3s CMD curl -f http://localhost:9876/health || exit 1
|
HEALTHCHECK --interval=15s --timeout=3s CMD curl -f http://localhost:9876/health || exit 1
|
||||||
|
97
Jenkinsfile
vendored
97
Jenkinsfile
vendored
@ -6,7 +6,7 @@ pipeline {
|
|||||||
agent any
|
agent any
|
||||||
environment {
|
environment {
|
||||||
IMAGE_NAME = "nginx-proxy-manager"
|
IMAGE_NAME = "nginx-proxy-manager"
|
||||||
BASE_IMAGE_NAME = "jc21/nginx-proxy-manager-base"
|
BASE_IMAGE_NAME = "jc21/nginx-proxy-manager-base:latest"
|
||||||
TEMP_IMAGE_NAME = "nginx-proxy-manager-build_${BUILD_NUMBER}"
|
TEMP_IMAGE_NAME = "nginx-proxy-manager-build_${BUILD_NUMBER}"
|
||||||
TEMP_IMAGE_NAME_ARM = "nginx-proxy-manager-arm-build_${BUILD_NUMBER}"
|
TEMP_IMAGE_NAME_ARM = "nginx-proxy-manager-arm-build_${BUILD_NUMBER}"
|
||||||
TAG_VERSION = getPackageVersion()
|
TAG_VERSION = getPackageVersion()
|
||||||
@ -18,35 +18,80 @@ pipeline {
|
|||||||
sh 'docker pull $DOCKER_CI_TOOLS'
|
sh 'docker pull $DOCKER_CI_TOOLS'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Build') {
|
stage('Build Develop') {
|
||||||
parallel {
|
when {
|
||||||
stage('x86_64') {
|
branch 'develop'
|
||||||
|
}
|
||||||
steps {
|
steps {
|
||||||
ansiColor('xterm') {
|
ansiColor('xterm') {
|
||||||
// Codebase
|
// Codebase
|
||||||
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME:latest yarn --registry=$NPM_REGISTRY install'
|
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME yarn install'
|
||||||
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME:latest npm run-script build'
|
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME npm run-script build'
|
||||||
sh 'rm -rf node_modules'
|
sh 'rm -rf node_modules'
|
||||||
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME:latest yarn --registry=$NPM_REGISTRY install --prod'
|
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME yarn install --prod'
|
||||||
sh 'docker run --rm -v $(pwd):/data $DOCKER_CI_TOOLS node-prune'
|
sh 'docker run --rm -v $(pwd):/data $DOCKER_CI_TOOLS node-prune'
|
||||||
|
|
||||||
// Docker Build
|
// Docker Build
|
||||||
sh 'docker build --pull --no-cache --squash --compress -t $TEMP_IMAGE_NAME .'
|
sh 'docker build --pull --no-cache --squash --compress -t $TEMP_IMAGE_NAME .'
|
||||||
|
|
||||||
|
// Dockerhub
|
||||||
|
sh 'docker tag $TEMP_IMAGE_NAME docker.io/jc21/$IMAGE_NAME:develop'
|
||||||
|
withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'dpass', usernameVariable: 'duser')]) {
|
||||||
|
sh "docker login -u '${duser}' -p '$dpass'"
|
||||||
|
sh 'docker push docker.io/jc21/$IMAGE_NAME:develop'
|
||||||
|
}
|
||||||
|
|
||||||
// Private Registry
|
// Private Registry
|
||||||
sh 'docker tag $TEMP_IMAGE_NAME $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$TAG_VERSION'
|
sh 'docker tag $TEMP_IMAGE_NAME $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:develop'
|
||||||
sh 'docker push $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$TAG_VERSION'
|
withCredentials([usernamePassword(credentialsId: 'jc21-private-registry', passwordVariable: 'dpass', usernameVariable: 'duser')]) {
|
||||||
sh 'docker tag $TEMP_IMAGE_NAME $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$MAJOR_VERSION'
|
sh "docker login -u '${duser}' -p '$dpass' $DOCKER_PRIVATE_REGISTRY"
|
||||||
sh 'docker push $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$MAJOR_VERSION'
|
sh 'docker push $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:develop'
|
||||||
|
}
|
||||||
|
|
||||||
|
sh 'docker rmi $TEMP_IMAGE_NAME'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Build Master') {
|
||||||
|
parallel {
|
||||||
|
stage('x86_64') {
|
||||||
|
when {
|
||||||
|
branch 'master'
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
ansiColor('xterm') {
|
||||||
|
// Codebase
|
||||||
|
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME yarn install'
|
||||||
|
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME npm run-script build'
|
||||||
|
sh 'rm -rf node_modules'
|
||||||
|
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME yarn install --prod'
|
||||||
|
sh 'docker run --rm -v $(pwd):/data $DOCKER_CI_TOOLS node-prune'
|
||||||
|
|
||||||
|
// Docker Build
|
||||||
|
sh 'docker build --pull --no-cache --squash --compress -t $TEMP_IMAGE_NAME .'
|
||||||
|
|
||||||
// Dockerhub
|
// Dockerhub
|
||||||
sh 'docker tag $TEMP_IMAGE_NAME docker.io/jc21/$IMAGE_NAME:$TAG_VERSION'
|
sh 'docker tag $TEMP_IMAGE_NAME docker.io/jc21/$IMAGE_NAME:$TAG_VERSION'
|
||||||
sh 'docker tag $TEMP_IMAGE_NAME docker.io/jc21/$IMAGE_NAME:$MAJOR_VERSION'
|
sh 'docker tag $TEMP_IMAGE_NAME docker.io/jc21/$IMAGE_NAME:$MAJOR_VERSION'
|
||||||
|
sh 'docker tag $TEMP_IMAGE_NAME docker.io/jc21/$IMAGE_NAME:latest'
|
||||||
|
|
||||||
withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'dpass', usernameVariable: 'duser')]) {
|
withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'dpass', usernameVariable: 'duser')]) {
|
||||||
sh "docker login -u '${duser}' -p '$dpass'"
|
sh "docker login -u '${duser}' -p '$dpass'"
|
||||||
sh 'docker push docker.io/jc21/$IMAGE_NAME:$TAG_VERSION'
|
sh 'docker push docker.io/jc21/$IMAGE_NAME:$TAG_VERSION'
|
||||||
sh 'docker push docker.io/jc21/$IMAGE_NAME:$MAJOR_VERSION'
|
sh 'docker push docker.io/jc21/$IMAGE_NAME:$MAJOR_VERSION'
|
||||||
|
sh 'docker push docker.io/jc21/$IMAGE_NAME:latest'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private Registry
|
||||||
|
sh 'docker tag $TEMP_IMAGE_NAME $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$TAG_VERSION'
|
||||||
|
sh 'docker tag $TEMP_IMAGE_NAME $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$MAJOR_VERSION'
|
||||||
|
sh 'docker tag $TEMP_IMAGE_NAME $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:latest'
|
||||||
|
|
||||||
|
withCredentials([usernamePassword(credentialsId: 'jc21-private-registry', passwordVariable: 'dpass', usernameVariable: 'duser')]) {
|
||||||
|
sh "docker login -u '${duser}' -p '$dpass' $DOCKER_PRIVATE_REGISTRY"
|
||||||
|
sh 'docker push $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$TAG_VERSION'
|
||||||
|
sh 'docker push $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$MAJOR_VERSION'
|
||||||
|
sh 'docker push $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:latest'
|
||||||
}
|
}
|
||||||
|
|
||||||
sh 'docker rmi $TEMP_IMAGE_NAME'
|
sh 'docker rmi $TEMP_IMAGE_NAME'
|
||||||
@ -54,34 +99,45 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('armhf') {
|
stage('armhf') {
|
||||||
|
when {
|
||||||
|
branch 'master'
|
||||||
|
}
|
||||||
agent {
|
agent {
|
||||||
label 'armhf'
|
label 'armhf'
|
||||||
}
|
}
|
||||||
steps {
|
steps {
|
||||||
ansiColor('xterm') {
|
ansiColor('xterm') {
|
||||||
// Codebase
|
// Codebase
|
||||||
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME:armhf yarn --registry=$NPM_REGISTRY install'
|
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME-armhf yarn install'
|
||||||
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME:armhf npm run-script build'
|
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME-armhf npm run-script build'
|
||||||
sh 'rm -rf node_modules'
|
sh 'rm -rf node_modules'
|
||||||
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME:armhf yarn --registry=$NPM_REGISTRY install --prod'
|
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME-armhf yarn install --prod'
|
||||||
|
|
||||||
// Docker Build
|
// Docker Build
|
||||||
sh 'docker build --pull --no-cache --squash --compress -t $TEMP_IMAGE_NAME_ARM -f Dockerfile.armhf .'
|
sh 'docker build --pull --no-cache --squash --compress -t $TEMP_IMAGE_NAME_ARM -f Dockerfile.armhf .'
|
||||||
|
|
||||||
// Private Registry
|
|
||||||
sh 'docker tag $TEMP_IMAGE_NAME_ARM $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$TAG_VERSION-armhf'
|
|
||||||
sh 'docker push $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$TAG_VERSION-armhf'
|
|
||||||
sh 'docker tag $TEMP_IMAGE_NAME_ARM $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$MAJOR_VERSION-armhf'
|
|
||||||
sh 'docker push $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$MAJOR_VERSION-armhf'
|
|
||||||
|
|
||||||
// Dockerhub
|
// Dockerhub
|
||||||
sh 'docker tag $TEMP_IMAGE_NAME_ARM docker.io/jc21/$IMAGE_NAME:$TAG_VERSION-armhf'
|
sh 'docker tag $TEMP_IMAGE_NAME_ARM docker.io/jc21/$IMAGE_NAME:$TAG_VERSION-armhf'
|
||||||
sh 'docker tag $TEMP_IMAGE_NAME_ARM docker.io/jc21/$IMAGE_NAME:$MAJOR_VERSION-armhf'
|
sh 'docker tag $TEMP_IMAGE_NAME_ARM docker.io/jc21/$IMAGE_NAME:$MAJOR_VERSION-armhf'
|
||||||
|
sh 'docker tag $TEMP_IMAGE_NAME_ARM docker.io/jc21/$IMAGE_NAME:latest-armhf'
|
||||||
|
|
||||||
withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'dpass', usernameVariable: 'duser')]) {
|
withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'dpass', usernameVariable: 'duser')]) {
|
||||||
sh "docker login -u '${duser}' -p '$dpass'"
|
sh "docker login -u '${duser}' -p '$dpass'"
|
||||||
sh 'docker push docker.io/jc21/$IMAGE_NAME:$TAG_VERSION-armhf'
|
sh 'docker push docker.io/jc21/$IMAGE_NAME:$TAG_VERSION-armhf'
|
||||||
sh 'docker push docker.io/jc21/$IMAGE_NAME:$MAJOR_VERSION-armhf'
|
sh 'docker push docker.io/jc21/$IMAGE_NAME:$MAJOR_VERSION-armhf'
|
||||||
|
sh 'docker push docker.io/jc21/$IMAGE_NAME:latest-armhf'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private Registry
|
||||||
|
sh 'docker tag $TEMP_IMAGE_NAME_ARM $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$TAG_VERSION-armhf'
|
||||||
|
sh 'docker tag $TEMP_IMAGE_NAME_ARM $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$MAJOR_VERSION-armhf'
|
||||||
|
sh 'docker tag $TEMP_IMAGE_NAME_ARM $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:latest-armhf'
|
||||||
|
|
||||||
|
withCredentials([usernamePassword(credentialsId: 'jc21-private-registry', passwordVariable: 'dpass', usernameVariable: 'duser')]) {
|
||||||
|
sh "docker login -u '${duser}' -p '$dpass' $DOCKER_PRIVATE_REGISTRY"
|
||||||
|
sh 'docker push $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$TAG_VERSION-armhf'
|
||||||
|
sh 'docker push $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$MAJOR_VERSION-armhf'
|
||||||
|
sh 'docker push $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:latest-armhf'
|
||||||
}
|
}
|
||||||
|
|
||||||
sh 'docker rmi $TEMP_IMAGE_NAME_ARM'
|
sh 'docker rmi $TEMP_IMAGE_NAME_ARM'
|
||||||
@ -107,3 +163,4 @@ def getPackageVersion() {
|
|||||||
ver = sh(script: 'docker run --rm -v $(pwd):/data $DOCKER_CI_TOOLS bash -c "cat /data/package.json|jq -r \'.version\'"', returnStdout: true)
|
ver = sh(script: 'docker run --rm -v $(pwd):/data $DOCKER_CI_TOOLS bash -c "cat /data/package.json|jq -r \'.version\'"', returnStdout: true)
|
||||||
return ver.trim()
|
return ver.trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Nginx Proxy Manager
|
# Nginx Proxy Manager
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
|
17
TODO.md
17
TODO.md
@ -1,17 +0,0 @@
|
|||||||
# TODO
|
|
||||||
|
|
||||||
- Dashboard stats are caching instead of querying
|
|
||||||
|
|
||||||
Next version:
|
|
||||||
|
|
||||||
- UI Log tail
|
|
||||||
- Enable/Disable a config
|
|
||||||
|
|
||||||
Testing:
|
|
||||||
|
|
||||||
- Access Levels
|
|
||||||
- Adding a proxy host without access to read certs or access lists
|
|
||||||
- Visibility
|
|
||||||
- Forwarding
|
|
||||||
- Cert renewals
|
|
||||||
- Custom certs
|
|
26
bin/migrate_create
Executable file
26
bin/migrate_create
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ "$1" == "" ]; then
|
||||||
|
echo "Error: migrate name must be specified as first arg"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
# Code path
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
if hash realpath 2>/dev/null; then
|
||||||
|
export CODEBASE=$(realpath $SCRIPT_DIR/..)
|
||||||
|
elif hash grealpath 2>/dev/null; then
|
||||||
|
export CODEBASE=$(grealpath $SCRIPT_DIR/..)
|
||||||
|
else
|
||||||
|
export CODEBASE=$(readlink -e $SCRIPT_DIR/..)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$CODEBASE" ]; then
|
||||||
|
echo "Unable to determine absolute codebase directory"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$CODEBASE"
|
||||||
|
|
||||||
|
sudo /usr/local/bin/docker-compose run --rm --no-deps app node node_modules/knex/bin/cli.js migrate:make "$1"
|
||||||
|
exit $?
|
||||||
|
fi
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Nginx Proxy Manager
|
# Nginx Proxy Manager
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
@ -14,16 +14,16 @@ running at home or otherwise, including free SSL, without having to know too muc
|
|||||||
|
|
||||||
## Tags
|
## Tags
|
||||||
|
|
||||||
* latest 1, 1.x.x ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/master/Dockerfile))
|
* latest 2, 2.x.x ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/master/Dockerfile))
|
||||||
* latest-armhf, 1-armhf, 1.x.x-armhf ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/master/Dockerfile.armhf))
|
* latest-armhf, 2-armhf, 2.x.x-armhf ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/master/Dockerfile.armhf))
|
||||||
* 2, 2.x.x ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/v2/Dockerfile))
|
* 1, 1.x.x ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/1.1.2/Dockerfile))
|
||||||
* 2-armhf, 2.x.x-armhf ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/v2/Dockerfile.armhf))
|
* 1-armhf, 1.x.x-armhf ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/1.1.2/Dockerfile.armhf))
|
||||||
|
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
Please consult the [installation instructions](https://github.com/jc21/nginx-proxy-manager/blob/v2/doc/INSTALL.md) for a complete guide or
|
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/v2/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 `docker-compose up -d`
|
||||||
|
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
@ -57,7 +57,7 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
db:
|
db:
|
||||||
image: mariadb
|
image: jc21/mariadb-aria
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: "password123"
|
MYSQL_ROOT_PASSWORD: "password123"
|
||||||
|
@ -17,7 +17,7 @@ services:
|
|||||||
# if you want pretty colors in your docker logs:
|
# if you want pretty colors in your docker logs:
|
||||||
- FORCE_COLOR=1
|
- FORCE_COLOR=1
|
||||||
db:
|
db:
|
||||||
image: mariadb
|
image: jc21/mariadb-aria
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: "password123"
|
MYSQL_ROOT_PASSWORD: "password123"
|
||||||
|
@ -11,6 +11,7 @@ services:
|
|||||||
- NODE_ENV=development
|
- NODE_ENV=development
|
||||||
- FORCE_COLOR=1
|
- FORCE_COLOR=1
|
||||||
volumes:
|
volumes:
|
||||||
|
- ./data:/data
|
||||||
- ./data/letsencrypt:/etc/letsencrypt
|
- ./data/letsencrypt:/etc/letsencrypt
|
||||||
- .:/app
|
- .:/app
|
||||||
- ./rootfs/etc/nginx:/etc/nginx
|
- ./rootfs/etc/nginx:/etc/nginx
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "nginx-proxy-manager",
|
"name": "nginx-proxy-manager",
|
||||||
"version": "2.0.0",
|
"version": "2.0.7",
|
||||||
"description": "A beautiful interface for creating Nginx endpoints",
|
"description": "A beautiful interface for creating Nginx endpoints",
|
||||||
"main": "src/backend/index.js",
|
"main": "src/backend/index.js",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -30,8 +30,8 @@
|
|||||||
"style-loader": "^0.22.1",
|
"style-loader": "^0.22.1",
|
||||||
"tabler-ui": "git+https://github.com/tabler/tabler.git",
|
"tabler-ui": "git+https://github.com/tabler/tabler.git",
|
||||||
"underscore": "^1.8.3",
|
"underscore": "^1.8.3",
|
||||||
"webpack": "^4.12.0",
|
"webpack": "^4.25.1",
|
||||||
"webpack-cli": "^3.0.8",
|
"webpack-cli": "^3.1.2",
|
||||||
"webpack-visualizer-plugin": "^0.1.11"
|
"webpack-visualizer-plugin": "^0.1.11"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -8,6 +8,7 @@ server {
|
|||||||
|
|
||||||
include conf.d/include/block-exploits.conf;
|
include conf.d/include/block-exploits.conf;
|
||||||
|
|
||||||
|
set $forward_scheme http;
|
||||||
set $server 127.0.0.1;
|
set $server 127.0.0.1;
|
||||||
set $port 81;
|
set $port 81;
|
||||||
|
|
||||||
@ -36,3 +37,17 @@ server {
|
|||||||
root /var/www/html;
|
root /var/www/html;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Default 443 Host
|
||||||
|
server {
|
||||||
|
listen 443 ssl default;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
access_log /data/logs/default.log proxy;
|
||||||
|
|
||||||
|
ssl_certificate /data/nginx/dummycert.pem;
|
||||||
|
ssl_certificate_key /data/nginx/dummykey.pem;
|
||||||
|
ssl_ciphers aNULL;
|
||||||
|
|
||||||
|
return 444;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
add_header X-Served-By $host;
|
add_header X-Served-By $host;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Forwarded-Scheme $scheme;
|
proxy_set_header X-Forwarded-Scheme $scheme;
|
||||||
proxy_set_header X-Forwarded-Protocol $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_set_header X-Forwarded-For $remote_addr;
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
proxy_pass http://$server:$port;
|
proxy_pass $forward_scheme://$server:$port;
|
||||||
|
1
rootfs/etc/nginx/conf.d/include/resolvers.conf
Normal file
1
rootfs/etc/nginx/conf.d/include/resolvers.conf
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Intentionally blank
|
@ -51,6 +51,15 @@ http {
|
|||||||
|
|
||||||
access_log /data/logs/default.log proxy;
|
access_log /data/logs/default.log proxy;
|
||||||
|
|
||||||
|
# Dynamically generated resolvers file
|
||||||
|
include /etc/nginx/conf.d/include/resolvers.conf;
|
||||||
|
|
||||||
|
# Default upstream scheme
|
||||||
|
map $host $forward_scheme {
|
||||||
|
default http;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Files generated by NPM
|
||||||
include /etc/nginx/conf.d/*.conf;
|
include /etc/nginx/conf.d/*.conf;
|
||||||
include /data/nginx/proxy_host/*.conf;
|
include /data/nginx/proxy_host/*.conf;
|
||||||
include /data/nginx/redirection_host/*.conf;
|
include /data/nginx/redirection_host/*.conf;
|
||||||
@ -59,6 +68,7 @@ http {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stream {
|
stream {
|
||||||
|
# Files generated by NPM
|
||||||
include /data/nginx/stream/*.conf;
|
include /data/nginx/stream/*.conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,4 +3,9 @@
|
|||||||
mkdir -p /data/letsencrypt-acme-challenge
|
mkdir -p /data/letsencrypt-acme-challenge
|
||||||
|
|
||||||
cd /app
|
cd /app
|
||||||
node --abort_on_uncaught_exception --max_old_space_size=250 /app/src/backend/index.js
|
|
||||||
|
while :
|
||||||
|
do
|
||||||
|
node --abort_on_uncaught_exception --max_old_space_size=250 /app/src/backend/index.js
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#!/usr/bin/with-contenv bash
|
#!/usr/bin/with-contenv bash
|
||||||
|
|
||||||
|
# Create required folders
|
||||||
mkdir -p /tmp/nginx/body \
|
mkdir -p /tmp/nginx/body \
|
||||||
/var/log/nginx \
|
/var/log/nginx \
|
||||||
/data/nginx \
|
/data/nginx \
|
||||||
@ -12,9 +13,30 @@ mkdir -p /tmp/nginx/body \
|
|||||||
/data/nginx/dead_host \
|
/data/nginx/dead_host \
|
||||||
/data/nginx/temp \
|
/data/nginx/temp \
|
||||||
/var/lib/nginx/cache/public \
|
/var/lib/nginx/cache/public \
|
||||||
/var/lib/nginx/cache/private
|
/var/lib/nginx/cache/private \
|
||||||
|
/var/cache/nginx/proxy_temp
|
||||||
|
|
||||||
touch /var/log/nginx/error.log && chmod 777 /var/log/nginx/error.log
|
touch /var/log/nginx/error.log && chmod 777 /var/log/nginx/error.log && chmod -R 777 /var/cache/nginx
|
||||||
chown root /tmp/nginx
|
chown root /tmp/nginx
|
||||||
|
|
||||||
|
# Dynamically generate resolvers file
|
||||||
|
echo resolver $(awk 'BEGIN{ORS=" "} $1=="nameserver" {print $2}' /etc/resolv.conf) ";" > /etc/nginx/conf.d/include/resolvers.conf
|
||||||
|
|
||||||
|
# Generate dummy self-signed certificate.
|
||||||
|
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]
|
||||||
|
then
|
||||||
|
echo "Generating dummy SSL certificate..."
|
||||||
|
openssl req \
|
||||||
|
-new \
|
||||||
|
-newkey rsa:2048 \
|
||||||
|
-days 3650 \
|
||||||
|
-nodes \
|
||||||
|
-x509 \
|
||||||
|
-subj '/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost' \
|
||||||
|
-keyout /data/nginx/dummykey.pem \
|
||||||
|
-out /data/nginx/dummycert.pem
|
||||||
|
echo "Complete"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run
|
||||||
exec nginx
|
exec nginx
|
||||||
|
@ -4,6 +4,7 @@ const fs = require('fs');
|
|||||||
const logger = require('./logger').import;
|
const logger = require('./logger').import;
|
||||||
const utils = require('./lib/utils');
|
const utils = require('./lib/utils');
|
||||||
const batchflow = require('batchflow');
|
const batchflow = require('batchflow');
|
||||||
|
const debug_mode = process.env.NODE_ENV !== 'production';
|
||||||
|
|
||||||
const internalProxyHost = require('./internal/proxy-host');
|
const internalProxyHost = require('./internal/proxy-host');
|
||||||
const internalRedirectionHost = require('./internal/redirection-host');
|
const internalRedirectionHost = require('./internal/redirection-host');
|
||||||
@ -353,7 +354,7 @@ module.exports = function () {
|
|||||||
.insertAndFetch({
|
.insertAndFetch({
|
||||||
owner_user_id: 1,
|
owner_user_id: 1,
|
||||||
domain_names: [host.hostname],
|
domain_names: [host.hostname],
|
||||||
forward_ip: host.forward_server,
|
forward_host: host.forward_server,
|
||||||
forward_port: host.forward_port,
|
forward_port: host.forward_port,
|
||||||
access_list_id: access_list_id,
|
access_list_id: access_list_id,
|
||||||
certificate_id: certificate_id,
|
certificate_id: certificate_id,
|
||||||
@ -534,6 +535,10 @@ module.exports = function () {
|
|||||||
);
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (debug_mode) {
|
||||||
|
logger.debug('Importer skipped');
|
||||||
|
}
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -183,10 +183,7 @@ const internalCertificate = {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return internalCertificate.writeCustomCert(certificate)
|
|
||||||
.then(() => {
|
|
||||||
return certificate;
|
return certificate;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}).then(certificate => {
|
}).then(certificate => {
|
||||||
|
|
||||||
@ -409,9 +406,13 @@ const internalCertificate = {
|
|||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
writeCustomCert: certificate => {
|
writeCustomCert: certificate => {
|
||||||
return new Promise((resolve, reject) => {
|
if (debug_mode) {
|
||||||
|
logger.info('Writing Custom Certificate:', certificate);
|
||||||
|
}
|
||||||
|
|
||||||
let dir = '/data/custom_ssl/npm-' + certificate.id;
|
let dir = '/data/custom_ssl/npm-' + certificate.id;
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
if (certificate.provider === 'letsencrypt') {
|
if (certificate.provider === 'letsencrypt') {
|
||||||
reject(new Error('Refusing to write letsencrypt certs here'));
|
reject(new Error('Refusing to write letsencrypt certs here'));
|
||||||
return;
|
return;
|
||||||
@ -549,8 +550,13 @@ const internalCertificate = {
|
|||||||
id: data.id,
|
id: data.id,
|
||||||
expires_on: certificateModel.raw('FROM_UNIXTIME(' + validations.certificate.dates.to + ')'),
|
expires_on: certificateModel.raw('FROM_UNIXTIME(' + validations.certificate.dates.to + ')'),
|
||||||
domain_names: [validations.certificate.cn],
|
domain_names: [validations.certificate.cn],
|
||||||
meta: row.meta
|
meta: _.clone(row.meta) // Prevent the update method from changing this value that we'll use later
|
||||||
});
|
})
|
||||||
|
.then(certificate => {
|
||||||
|
console.log('ROWMETA:', row.meta);
|
||||||
|
certificate.meta = row.meta;
|
||||||
|
return internalCertificate.writeCustomCert(certificate);
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return _.pick(row.meta, internalCertificate.allowed_ssl_files);
|
return _.pick(row.meta, internalCertificate.allowed_ssl_files);
|
||||||
|
@ -189,7 +189,9 @@ const internalDeadHost = {
|
|||||||
.then(row => {
|
.then(row => {
|
||||||
// Configure nginx
|
// Configure nginx
|
||||||
return internalNginx.configure(deadHostModel, 'dead_host', row)
|
return internalNginx.configure(deadHostModel, 'dead_host', row)
|
||||||
.then(() => {
|
.then(new_meta => {
|
||||||
|
row.meta = new_meta;
|
||||||
|
row = internalHost.cleanRowCertificateMeta(row);
|
||||||
return _.omit(row, omissions());
|
return _.omit(row, omissions());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -235,6 +237,7 @@ const internalDeadHost = {
|
|||||||
})
|
})
|
||||||
.then(row => {
|
.then(row => {
|
||||||
if (row) {
|
if (row) {
|
||||||
|
row = internalHost.cleanRowCertificateMeta(row);
|
||||||
return _.omit(row, omissions());
|
return _.omit(row, omissions());
|
||||||
} else {
|
} else {
|
||||||
throw new error.ItemNotFoundError(data.id);
|
throw new error.ItemNotFoundError(data.id);
|
||||||
@ -322,6 +325,13 @@ const internalDeadHost = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
|
})
|
||||||
|
.then(rows => {
|
||||||
|
if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) {
|
||||||
|
return internalHost.cleanAllRowsCertificateMeta(rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -6,6 +6,36 @@ const deadHostModel = require('../models/dead_host');
|
|||||||
|
|
||||||
const internalHost = {
|
const internalHost = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used by the getAll functions of hosts, this removes the certificate meta if present
|
||||||
|
*
|
||||||
|
* @param {Array} rows
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
cleanAllRowsCertificateMeta: function (rows) {
|
||||||
|
rows.map(function (row, idx) {
|
||||||
|
if (typeof rows[idx].certificate !== 'undefined' && rows[idx].certificate) {
|
||||||
|
rows[idx].certificate.meta = {};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return rows;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used by the get/update functions of hosts, this removes the certificate meta if present
|
||||||
|
*
|
||||||
|
* @param {Object} row
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
cleanRowCertificateMeta: function (row) {
|
||||||
|
if (typeof row.certificate !== 'undefined' && row.certificate) {
|
||||||
|
row.certificate.meta = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return row;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This returns all the host types with any domain listed in the provided domain_names array.
|
* This returns all the host types with any domain listed in the provided domain_names array.
|
||||||
* This is used by the certificates to temporarily disable any host that is using the domain
|
* This is used by the certificates to temporarily disable any host that is using the domain
|
||||||
|
@ -25,6 +25,8 @@ const internalNginx = {
|
|||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
configure: (model, host_type, host) => {
|
configure: (model, host_type, host) => {
|
||||||
|
let combined_meta = {};
|
||||||
|
|
||||||
return internalNginx.test()
|
return internalNginx.test()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// Nginx is OK
|
// Nginx is OK
|
||||||
@ -39,30 +41,46 @@ const internalNginx = {
|
|||||||
return internalNginx.test()
|
return internalNginx.test()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// nginx is ok
|
// nginx is ok
|
||||||
|
combined_meta = _.assign({}, host.meta, {
|
||||||
|
nginx_online: true,
|
||||||
|
nginx_err: null
|
||||||
|
});
|
||||||
|
|
||||||
return model
|
return model
|
||||||
.query()
|
.query()
|
||||||
.where('id', host.id)
|
.where('id', host.id)
|
||||||
.patch({
|
.patch({
|
||||||
meta: _.assign({}, host.meta, {
|
meta: combined_meta
|
||||||
nginx_online: true,
|
|
||||||
nginx_err: null
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
// Remove the error_log line because it's a docker-ism false positive that doesn't need to be reported.
|
||||||
|
// It will always look like this:
|
||||||
|
// nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (6: No such device or address)
|
||||||
|
|
||||||
|
let valid_lines = [];
|
||||||
|
let err_lines = err.message.split("\n");
|
||||||
|
err_lines.map(function (line) {
|
||||||
|
if (line.indexOf('/var/log/nginx/error.log') === -1) {
|
||||||
|
valid_lines.push(line);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (debug_mode) {
|
if (debug_mode) {
|
||||||
logger.error('Nginx test failed:', err.message);
|
logger.error('Nginx test failed:', valid_lines.join("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// config is bad, update meta and delete config
|
// config is bad, update meta and delete config
|
||||||
|
combined_meta = _.assign({}, host.meta, {
|
||||||
|
nginx_online: false,
|
||||||
|
nginx_err: valid_lines.join("\n")
|
||||||
|
});
|
||||||
|
|
||||||
return model
|
return model
|
||||||
.query()
|
.query()
|
||||||
.where('id', host.id)
|
.where('id', host.id)
|
||||||
.patch({
|
.patch({
|
||||||
meta: _.assign({}, host.meta, {
|
meta: combined_meta
|
||||||
nginx_online: false,
|
|
||||||
nginx_err: err.message
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return internalNginx.deleteConfig(host_type, host, true);
|
return internalNginx.deleteConfig(host_type, host, true);
|
||||||
@ -71,7 +89,10 @@ const internalNginx = {
|
|||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return internalNginx.reload();
|
return internalNginx.reload();
|
||||||
});
|
})
|
||||||
|
.then(() => {
|
||||||
|
return combined_meta;
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,7 +103,7 @@ const internalNginx = {
|
|||||||
logger.info('Testing Nginx configuration');
|
logger.info('Testing Nginx configuration');
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.exec('/usr/sbin/nginx -t');
|
return utils.exec('/usr/sbin/nginx -t -g "error_log off;"');
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -163,7 +163,7 @@ const internalProxyHost = {
|
|||||||
// Add domain_names to the data in case it isn't there, so that the audit log renders correctly. The order is important here.
|
// Add domain_names to the data in case it isn't there, so that the audit log renders correctly. The order is important here.
|
||||||
data = _.assign({}, {
|
data = _.assign({}, {
|
||||||
domain_names: row.domain_names
|
domain_names: row.domain_names
|
||||||
},data);
|
}, data);
|
||||||
|
|
||||||
return proxyHostModel
|
return proxyHostModel
|
||||||
.query()
|
.query()
|
||||||
@ -190,7 +190,9 @@ const internalProxyHost = {
|
|||||||
.then(row => {
|
.then(row => {
|
||||||
// Configure nginx
|
// Configure nginx
|
||||||
return internalNginx.configure(proxyHostModel, 'proxy_host', row)
|
return internalNginx.configure(proxyHostModel, 'proxy_host', row)
|
||||||
.then(() => {
|
.then(new_meta => {
|
||||||
|
row.meta = new_meta;
|
||||||
|
row = internalHost.cleanRowCertificateMeta(row);
|
||||||
return _.omit(row, omissions());
|
return _.omit(row, omissions());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -236,6 +238,7 @@ const internalProxyHost = {
|
|||||||
})
|
})
|
||||||
.then(row => {
|
.then(row => {
|
||||||
if (row) {
|
if (row) {
|
||||||
|
row = internalHost.cleanRowCertificateMeta(row);
|
||||||
return _.omit(row, omissions());
|
return _.omit(row, omissions());
|
||||||
} else {
|
} else {
|
||||||
throw new error.ItemNotFoundError(data.id);
|
throw new error.ItemNotFoundError(data.id);
|
||||||
@ -323,6 +326,13 @@ const internalProxyHost = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
|
})
|
||||||
|
.then(rows => {
|
||||||
|
if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) {
|
||||||
|
return internalHost.cleanAllRowsCertificateMeta(rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -189,7 +189,9 @@ const internalRedirectionHost = {
|
|||||||
.then(row => {
|
.then(row => {
|
||||||
// Configure nginx
|
// Configure nginx
|
||||||
return internalNginx.configure(redirectionHostModel, 'redirection_host', row)
|
return internalNginx.configure(redirectionHostModel, 'redirection_host', row)
|
||||||
.then(() => {
|
.then(new_meta => {
|
||||||
|
row.meta = new_meta;
|
||||||
|
row = internalHost.cleanRowCertificateMeta(row);
|
||||||
return _.omit(row, omissions());
|
return _.omit(row, omissions());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -235,6 +237,7 @@ const internalRedirectionHost = {
|
|||||||
})
|
})
|
||||||
.then(row => {
|
.then(row => {
|
||||||
if (row) {
|
if (row) {
|
||||||
|
row = internalHost.cleanRowCertificateMeta(row);
|
||||||
return _.omit(row, omissions());
|
return _.omit(row, omissions());
|
||||||
} else {
|
} else {
|
||||||
throw new error.ItemNotFoundError(data.id);
|
throw new error.ItemNotFoundError(data.id);
|
||||||
@ -322,6 +325,13 @@ const internalRedirectionHost = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
|
})
|
||||||
|
.then(rows => {
|
||||||
|
if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) {
|
||||||
|
return internalHost.cleanAllRowsCertificateMeta(rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -8,4 +8,5 @@ module.exports = {
|
|||||||
nginx: new Signale({scope: 'Nginx '}),
|
nginx: new Signale({scope: 'Nginx '}),
|
||||||
ssl: new Signale({scope: 'SSL '}),
|
ssl: new Signale({scope: 'SSL '}),
|
||||||
import: new Signale({scope: 'Importer'}),
|
import: new Signale({scope: 'Importer'}),
|
||||||
|
setup: new Signale({scope: 'Setup '})
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,7 @@ exports.up = function (knex/*, Promise*/) {
|
|||||||
table.integer('user_id').notNull().unsigned();
|
table.integer('user_id').notNull().unsigned();
|
||||||
table.string('type', 30).notNull();
|
table.string('type', 30).notNull();
|
||||||
table.string('secret').notNull();
|
table.string('secret').notNull();
|
||||||
table.json('meta').notNull().defaultTo('{}');
|
table.json('meta').notNull();
|
||||||
table.integer('is_deleted').notNull().unsigned().defaultTo(0);
|
table.integer('is_deleted').notNull().unsigned().defaultTo(0);
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -77,7 +77,7 @@ exports.up = function (knex/*, Promise*/) {
|
|||||||
table.integer('caching_enabled').notNull().unsigned().defaultTo(0);
|
table.integer('caching_enabled').notNull().unsigned().defaultTo(0);
|
||||||
table.integer('block_exploits').notNull().unsigned().defaultTo(0);
|
table.integer('block_exploits').notNull().unsigned().defaultTo(0);
|
||||||
table.text('advanced_config').notNull().defaultTo('');
|
table.text('advanced_config').notNull().defaultTo('');
|
||||||
table.json('meta').notNull().defaultTo('{}');
|
table.json('meta').notNull();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -96,7 +96,7 @@ exports.up = function (knex/*, Promise*/) {
|
|||||||
table.integer('ssl_forced').notNull().unsigned().defaultTo(0);
|
table.integer('ssl_forced').notNull().unsigned().defaultTo(0);
|
||||||
table.integer('block_exploits').notNull().unsigned().defaultTo(0);
|
table.integer('block_exploits').notNull().unsigned().defaultTo(0);
|
||||||
table.text('advanced_config').notNull().defaultTo('');
|
table.text('advanced_config').notNull().defaultTo('');
|
||||||
table.json('meta').notNull().defaultTo('{}');
|
table.json('meta').notNull();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -112,7 +112,7 @@ exports.up = function (knex/*, Promise*/) {
|
|||||||
table.integer('certificate_id').notNull().unsigned().defaultTo(0);
|
table.integer('certificate_id').notNull().unsigned().defaultTo(0);
|
||||||
table.integer('ssl_forced').notNull().unsigned().defaultTo(0);
|
table.integer('ssl_forced').notNull().unsigned().defaultTo(0);
|
||||||
table.text('advanced_config').notNull().defaultTo('');
|
table.text('advanced_config').notNull().defaultTo('');
|
||||||
table.json('meta').notNull().defaultTo('{}');
|
table.json('meta').notNull();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -129,7 +129,7 @@ exports.up = function (knex/*, Promise*/) {
|
|||||||
table.integer('forwarding_port').notNull().unsigned();
|
table.integer('forwarding_port').notNull().unsigned();
|
||||||
table.integer('tcp_forwarding').notNull().unsigned().defaultTo(0);
|
table.integer('tcp_forwarding').notNull().unsigned().defaultTo(0);
|
||||||
table.integer('udp_forwarding').notNull().unsigned().defaultTo(0);
|
table.integer('udp_forwarding').notNull().unsigned().defaultTo(0);
|
||||||
table.json('meta').notNull().defaultTo('{}');
|
table.json('meta').notNull();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -142,7 +142,7 @@ exports.up = function (knex/*, Promise*/) {
|
|||||||
table.integer('owner_user_id').notNull().unsigned();
|
table.integer('owner_user_id').notNull().unsigned();
|
||||||
table.integer('is_deleted').notNull().unsigned().defaultTo(0);
|
table.integer('is_deleted').notNull().unsigned().defaultTo(0);
|
||||||
table.string('name').notNull();
|
table.string('name').notNull();
|
||||||
table.json('meta').notNull().defaultTo('{}');
|
table.json('meta').notNull();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -156,9 +156,9 @@ exports.up = function (knex/*, Promise*/) {
|
|||||||
table.integer('is_deleted').notNull().unsigned().defaultTo(0);
|
table.integer('is_deleted').notNull().unsigned().defaultTo(0);
|
||||||
table.string('provider').notNull();
|
table.string('provider').notNull();
|
||||||
table.string('nice_name').notNull().defaultTo('');
|
table.string('nice_name').notNull().defaultTo('');
|
||||||
table.json('domain_names').notNull().defaultTo('[]');
|
table.json('domain_names').notNull();
|
||||||
table.dateTime('expires_on').notNull();
|
table.dateTime('expires_on').notNull();
|
||||||
table.json('meta').notNull().defaultTo('{}');
|
table.json('meta').notNull();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -171,7 +171,7 @@ exports.up = function (knex/*, Promise*/) {
|
|||||||
table.integer('access_list_id').notNull().unsigned();
|
table.integer('access_list_id').notNull().unsigned();
|
||||||
table.string('username').notNull();
|
table.string('username').notNull();
|
||||||
table.string('password').notNull();
|
table.string('password').notNull();
|
||||||
table.json('meta').notNull().defaultTo('{}');
|
table.json('meta').notNull();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -185,7 +185,7 @@ exports.up = function (knex/*, Promise*/) {
|
|||||||
table.string('object_type').notNull().defaultTo('');
|
table.string('object_type').notNull().defaultTo('');
|
||||||
table.integer('object_id').notNull().unsigned().defaultTo(0);
|
table.integer('object_id').notNull().unsigned().defaultTo(0);
|
||||||
table.string('action').notNull();
|
table.string('action').notNull();
|
||||||
table.json('meta').notNull().defaultTo('{}');
|
table.json('meta').notNull();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
37
src/backend/migrations/20180929054513_websockets.js
Normal file
37
src/backend/migrations/20180929054513_websockets.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const migrate_name = 'websockets';
|
||||||
|
const logger = require('../logger').migrate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate
|
||||||
|
*
|
||||||
|
* @see http://knexjs.org/#Schema
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.up = function (knex/*, Promise*/) {
|
||||||
|
logger.info('[' + migrate_name + '] Migrating Up...');
|
||||||
|
|
||||||
|
return knex.schema.table('proxy_host', function (proxy_host) {
|
||||||
|
proxy_host.integer('allow_websocket_upgrade').notNull().unsigned().defaultTo(0);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
logger.info('[' + migrate_name + '] proxy_host Table altered');
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo Migrate
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.down = function (knex, Promise) {
|
||||||
|
logger.warn('[' + migrate_name + '] You can\'t migrate down this one.');
|
||||||
|
return Promise.resolve(true);
|
||||||
|
};
|
36
src/backend/migrations/20181019052346_forward_host.js
Normal file
36
src/backend/migrations/20181019052346_forward_host.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const migrate_name = 'forward_host';
|
||||||
|
const logger = require('../logger').migrate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate
|
||||||
|
*
|
||||||
|
* @see http://knexjs.org/#Schema
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.up = function (knex/*, Promise*/) {
|
||||||
|
logger.info('[' + migrate_name + '] Migrating Up...');
|
||||||
|
|
||||||
|
return knex.schema.table('proxy_host', function (proxy_host) {
|
||||||
|
proxy_host.renameColumn('forward_ip', 'forward_host');
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
logger.info('[' + migrate_name + '] proxy_host Table altered');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo Migrate
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.down = function (knex, Promise) {
|
||||||
|
logger.warn('[' + migrate_name + '] You can\'t migrate down this one.');
|
||||||
|
return Promise.resolve(true);
|
||||||
|
};
|
51
src/backend/migrations/20181113041458_http2_support.js
Normal file
51
src/backend/migrations/20181113041458_http2_support.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const migrate_name = 'http2_support';
|
||||||
|
const logger = require('../logger').migrate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate
|
||||||
|
*
|
||||||
|
* @see http://knexjs.org/#Schema
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.up = function (knex/*, Promise*/) {
|
||||||
|
logger.info('[' + migrate_name + '] Migrating Up...');
|
||||||
|
|
||||||
|
return knex.schema.table('proxy_host', function (proxy_host) {
|
||||||
|
proxy_host.integer('http2_support').notNull().unsigned().defaultTo(0);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
logger.info('[' + migrate_name + '] proxy_host Table altered');
|
||||||
|
|
||||||
|
return knex.schema.table('redirection_host', function (redirection_host) {
|
||||||
|
redirection_host.integer('http2_support').notNull().unsigned().defaultTo(0);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
logger.info('[' + migrate_name + '] redirection_host Table altered');
|
||||||
|
|
||||||
|
return knex.schema.table('dead_host', function (dead_host) {
|
||||||
|
dead_host.integer('http2_support').notNull().unsigned().defaultTo(0);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
logger.info('[' + migrate_name + '] dead_host Table altered');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo Migrate
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.down = function (knex, Promise) {
|
||||||
|
logger.warn('[' + migrate_name + '] You can\'t migrate down this one.');
|
||||||
|
return Promise.resolve(true);
|
||||||
|
};
|
||||||
|
|
36
src/backend/migrations/20181213013211_forward_scheme.js
Normal file
36
src/backend/migrations/20181213013211_forward_scheme.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const migrate_name = 'forward_scheme';
|
||||||
|
const logger = require('../logger').migrate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate
|
||||||
|
*
|
||||||
|
* @see http://knexjs.org/#Schema
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.up = function (knex/*, Promise*/) {
|
||||||
|
logger.info('[' + migrate_name + '] Migrating Up...');
|
||||||
|
|
||||||
|
return knex.schema.table('proxy_host', function (proxy_host) {
|
||||||
|
proxy_host.string('forward_scheme').notNull().defaultTo('http');
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
logger.info('[' + migrate_name + '] proxy_host Table altered');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo Migrate
|
||||||
|
*
|
||||||
|
* @param {Object} knex
|
||||||
|
* @param {Promise} Promise
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
exports.down = function (knex, Promise) {
|
||||||
|
logger.warn('[' + migrate_name + '] You can\'t migrate down this one.');
|
||||||
|
return Promise.resolve(true);
|
||||||
|
};
|
@ -14,6 +14,11 @@ class AccessList extends Model {
|
|||||||
$beforeInsert () {
|
$beforeInsert () {
|
||||||
this.created_on = Model.raw('NOW()');
|
this.created_on = Model.raw('NOW()');
|
||||||
this.modified_on = Model.raw('NOW()');
|
this.modified_on = Model.raw('NOW()');
|
||||||
|
|
||||||
|
// Default for meta
|
||||||
|
if (typeof this.meta === 'undefined') {
|
||||||
|
this.meta = {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$beforeUpdate () {
|
$beforeUpdate () {
|
||||||
|
@ -12,6 +12,11 @@ class AccessListAuth extends Model {
|
|||||||
$beforeInsert () {
|
$beforeInsert () {
|
||||||
this.created_on = Model.raw('NOW()');
|
this.created_on = Model.raw('NOW()');
|
||||||
this.modified_on = Model.raw('NOW()');
|
this.modified_on = Model.raw('NOW()');
|
||||||
|
|
||||||
|
// Default for meta
|
||||||
|
if (typeof this.meta === 'undefined') {
|
||||||
|
this.meta = {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$beforeUpdate () {
|
$beforeUpdate () {
|
||||||
|
@ -13,6 +13,11 @@ class AuditLog extends Model {
|
|||||||
$beforeInsert () {
|
$beforeInsert () {
|
||||||
this.created_on = Model.raw('NOW()');
|
this.created_on = Model.raw('NOW()');
|
||||||
this.modified_on = Model.raw('NOW()');
|
this.modified_on = Model.raw('NOW()');
|
||||||
|
|
||||||
|
// Default for meta
|
||||||
|
if (typeof this.meta === 'undefined') {
|
||||||
|
this.meta = {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$beforeUpdate () {
|
$beforeUpdate () {
|
||||||
|
@ -29,6 +29,11 @@ class Auth extends Model {
|
|||||||
this.created_on = Model.raw('NOW()');
|
this.created_on = Model.raw('NOW()');
|
||||||
this.modified_on = Model.raw('NOW()');
|
this.modified_on = Model.raw('NOW()');
|
||||||
|
|
||||||
|
// Default for meta
|
||||||
|
if (typeof this.meta === 'undefined') {
|
||||||
|
this.meta = {};
|
||||||
|
}
|
||||||
|
|
||||||
return encryptPassword.apply(this, queryContext);
|
return encryptPassword.apply(this, queryContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,13 +14,31 @@ class Certificate extends Model {
|
|||||||
this.created_on = Model.raw('NOW()');
|
this.created_on = Model.raw('NOW()');
|
||||||
this.modified_on = Model.raw('NOW()');
|
this.modified_on = Model.raw('NOW()');
|
||||||
|
|
||||||
|
// Default for expires_on
|
||||||
if (typeof this.expires_on === 'undefined') {
|
if (typeof this.expires_on === 'undefined') {
|
||||||
this.expires_on = Model.raw('NOW()');
|
this.expires_on = Model.raw('NOW()');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default for domain_names
|
||||||
|
if (typeof this.domain_names === 'undefined') {
|
||||||
|
this.domain_names = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default for meta
|
||||||
|
if (typeof this.meta === 'undefined') {
|
||||||
|
this.meta = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.domain_names.sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
$beforeUpdate () {
|
$beforeUpdate () {
|
||||||
this.modified_on = Model.raw('NOW()');
|
this.modified_on = Model.raw('NOW()');
|
||||||
|
|
||||||
|
// Sort domain_names
|
||||||
|
if (typeof this.domain_names !== 'undefined') {
|
||||||
|
this.domain_names.sort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get name () {
|
static get name () {
|
||||||
|
@ -14,10 +14,27 @@ class DeadHost extends Model {
|
|||||||
$beforeInsert () {
|
$beforeInsert () {
|
||||||
this.created_on = Model.raw('NOW()');
|
this.created_on = Model.raw('NOW()');
|
||||||
this.modified_on = Model.raw('NOW()');
|
this.modified_on = Model.raw('NOW()');
|
||||||
|
|
||||||
|
// Default for domain_names
|
||||||
|
if (typeof this.domain_names === 'undefined') {
|
||||||
|
this.domain_names = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default for meta
|
||||||
|
if (typeof this.meta === 'undefined') {
|
||||||
|
this.meta = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.domain_names.sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
$beforeUpdate () {
|
$beforeUpdate () {
|
||||||
this.modified_on = Model.raw('NOW()');
|
this.modified_on = Model.raw('NOW()');
|
||||||
|
|
||||||
|
// Sort domain_names
|
||||||
|
if (typeof this.domain_names !== 'undefined') {
|
||||||
|
this.domain_names.sort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get name () {
|
static get name () {
|
||||||
|
@ -15,11 +15,24 @@ class ProxyHost extends Model {
|
|||||||
$beforeInsert () {
|
$beforeInsert () {
|
||||||
this.created_on = Model.raw('NOW()');
|
this.created_on = Model.raw('NOW()');
|
||||||
this.modified_on = Model.raw('NOW()');
|
this.modified_on = Model.raw('NOW()');
|
||||||
|
|
||||||
|
// Default for domain_names
|
||||||
|
if (typeof this.domain_names === 'undefined') {
|
||||||
|
this.domain_names = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default for meta
|
||||||
|
if (typeof this.meta === 'undefined') {
|
||||||
|
this.meta = {};
|
||||||
|
}
|
||||||
|
|
||||||
this.domain_names.sort();
|
this.domain_names.sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
$beforeUpdate () {
|
$beforeUpdate () {
|
||||||
this.modified_on = Model.raw('NOW()');
|
this.modified_on = Model.raw('NOW()');
|
||||||
|
|
||||||
|
// Sort domain_names
|
||||||
if (typeof this.domain_names !== 'undefined') {
|
if (typeof this.domain_names !== 'undefined') {
|
||||||
this.domain_names.sort();
|
this.domain_names.sort();
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,27 @@ class RedirectionHost extends Model {
|
|||||||
$beforeInsert () {
|
$beforeInsert () {
|
||||||
this.created_on = Model.raw('NOW()');
|
this.created_on = Model.raw('NOW()');
|
||||||
this.modified_on = Model.raw('NOW()');
|
this.modified_on = Model.raw('NOW()');
|
||||||
|
|
||||||
|
// Default for domain_names
|
||||||
|
if (typeof this.domain_names === 'undefined') {
|
||||||
|
this.domain_names = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default for meta
|
||||||
|
if (typeof this.meta === 'undefined') {
|
||||||
|
this.meta = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.domain_names.sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
$beforeUpdate () {
|
$beforeUpdate () {
|
||||||
this.modified_on = Model.raw('NOW()');
|
this.modified_on = Model.raw('NOW()');
|
||||||
|
|
||||||
|
// Sort domain_names
|
||||||
|
if (typeof this.domain_names !== 'undefined') {
|
||||||
|
this.domain_names.sort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get name () {
|
static get name () {
|
||||||
|
@ -13,6 +13,11 @@ class Stream extends Model {
|
|||||||
$beforeInsert () {
|
$beforeInsert () {
|
||||||
this.created_on = Model.raw('NOW()');
|
this.created_on = Model.raw('NOW()');
|
||||||
this.modified_on = Model.raw('NOW()');
|
this.modified_on = Model.raw('NOW()');
|
||||||
|
|
||||||
|
// Default for meta
|
||||||
|
if (typeof this.meta === 'undefined') {
|
||||||
|
this.meta = {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$beforeUpdate () {
|
$beforeUpdate () {
|
||||||
|
@ -19,7 +19,6 @@ module.exports = function () {
|
|||||||
let token_data = {};
|
let token_data = {};
|
||||||
|
|
||||||
let self = {
|
let self = {
|
||||||
//return {
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} payload
|
* @param {Object} payload
|
||||||
* @param {Object} [user_options]
|
* @param {Object} [user_options]
|
||||||
|
@ -13,6 +13,11 @@ class User extends Model {
|
|||||||
$beforeInsert () {
|
$beforeInsert () {
|
||||||
this.created_on = Model.raw('NOW()');
|
this.created_on = Model.raw('NOW()');
|
||||||
this.modified_on = Model.raw('NOW()');
|
this.modified_on = Model.raw('NOW()');
|
||||||
|
|
||||||
|
// Default for roles
|
||||||
|
if (typeof this.roles === 'undefined') {
|
||||||
|
this.roles = [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$beforeUpdate () {
|
$beforeUpdate () {
|
||||||
|
@ -186,6 +186,11 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"pattern": "^(letsencrypt|other)$"
|
"pattern": "^(letsencrypt|other)$"
|
||||||
},
|
},
|
||||||
|
"http2_support": {
|
||||||
|
"description": "HTTP2 Protocol Support",
|
||||||
|
"example": false,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"block_exploits": {
|
"block_exploits": {
|
||||||
"description": "Should we block common exploits",
|
"description": "Should we block common exploits",
|
||||||
"example": true,
|
"example": true,
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
"ssl_forced": {
|
"ssl_forced": {
|
||||||
"$ref": "../definitions.json#/definitions/ssl_forced"
|
"$ref": "../definitions.json#/definitions/ssl_forced"
|
||||||
},
|
},
|
||||||
|
"http2_support": {
|
||||||
|
"$ref": "../definitions.json#/definitions/http2_support"
|
||||||
|
},
|
||||||
"advanced_config": {
|
"advanced_config": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -50,6 +53,9 @@
|
|||||||
"ssl_forced": {
|
"ssl_forced": {
|
||||||
"$ref": "#/definitions/ssl_forced"
|
"$ref": "#/definitions/ssl_forced"
|
||||||
},
|
},
|
||||||
|
"http2_support": {
|
||||||
|
"$ref": "#/definitions/http2_support"
|
||||||
|
},
|
||||||
"advanced_config": {
|
"advanced_config": {
|
||||||
"$ref": "#/definitions/advanced_config"
|
"$ref": "#/definitions/advanced_config"
|
||||||
},
|
},
|
||||||
@ -101,6 +107,9 @@
|
|||||||
"ssl_forced": {
|
"ssl_forced": {
|
||||||
"$ref": "#/definitions/ssl_forced"
|
"$ref": "#/definitions/ssl_forced"
|
||||||
},
|
},
|
||||||
|
"http2_support": {
|
||||||
|
"$ref": "#/definitions/http2_support"
|
||||||
|
},
|
||||||
"advanced_config": {
|
"advanced_config": {
|
||||||
"$ref": "#/definitions/advanced_config"
|
"$ref": "#/definitions/advanced_config"
|
||||||
},
|
},
|
||||||
@ -138,6 +147,9 @@
|
|||||||
"ssl_forced": {
|
"ssl_forced": {
|
||||||
"$ref": "#/definitions/ssl_forced"
|
"$ref": "#/definitions/ssl_forced"
|
||||||
},
|
},
|
||||||
|
"http2_support": {
|
||||||
|
"$ref": "#/definitions/http2_support"
|
||||||
|
},
|
||||||
"advanced_config": {
|
"advanced_config": {
|
||||||
"$ref": "#/definitions/advanced_config"
|
"$ref": "#/definitions/advanced_config"
|
||||||
},
|
},
|
||||||
|
@ -18,9 +18,14 @@
|
|||||||
"domain_names": {
|
"domain_names": {
|
||||||
"$ref": "../definitions.json#/definitions/domain_names"
|
"$ref": "../definitions.json#/definitions/domain_names"
|
||||||
},
|
},
|
||||||
"forward_ip": {
|
"forward_scheme": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "ipv4"
|
"enum": ["http", "https"]
|
||||||
|
},
|
||||||
|
"forward_host": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 50
|
||||||
},
|
},
|
||||||
"forward_port": {
|
"forward_port": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
@ -33,12 +38,20 @@
|
|||||||
"ssl_forced": {
|
"ssl_forced": {
|
||||||
"$ref": "../definitions.json#/definitions/ssl_forced"
|
"$ref": "../definitions.json#/definitions/ssl_forced"
|
||||||
},
|
},
|
||||||
|
"http2_support": {
|
||||||
|
"$ref": "../definitions.json#/definitions/http2_support"
|
||||||
|
},
|
||||||
"block_exploits": {
|
"block_exploits": {
|
||||||
"$ref": "../definitions.json#/definitions/block_exploits"
|
"$ref": "../definitions.json#/definitions/block_exploits"
|
||||||
},
|
},
|
||||||
"caching_enabled": {
|
"caching_enabled": {
|
||||||
"$ref": "../definitions.json#/definitions/caching_enabled"
|
"$ref": "../definitions.json#/definitions/caching_enabled"
|
||||||
},
|
},
|
||||||
|
"allow_websocket_upgrade": {
|
||||||
|
"description": "Allow Websocket Upgrade for all paths",
|
||||||
|
"example": true,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"access_list_id": {
|
"access_list_id": {
|
||||||
"$ref": "../definitions.json#/definitions/access_list_id"
|
"$ref": "../definitions.json#/definitions/access_list_id"
|
||||||
},
|
},
|
||||||
@ -62,8 +75,11 @@
|
|||||||
"domain_names": {
|
"domain_names": {
|
||||||
"$ref": "#/definitions/domain_names"
|
"$ref": "#/definitions/domain_names"
|
||||||
},
|
},
|
||||||
"forward_ip": {
|
"forward_scheme": {
|
||||||
"$ref": "#/definitions/forward_ip"
|
"$ref": "#/definitions/forward_scheme"
|
||||||
|
},
|
||||||
|
"forward_host": {
|
||||||
|
"$ref": "#/definitions/forward_host"
|
||||||
},
|
},
|
||||||
"forward_port": {
|
"forward_port": {
|
||||||
"$ref": "#/definitions/forward_port"
|
"$ref": "#/definitions/forward_port"
|
||||||
@ -74,12 +90,18 @@
|
|||||||
"ssl_forced": {
|
"ssl_forced": {
|
||||||
"$ref": "#/definitions/ssl_forced"
|
"$ref": "#/definitions/ssl_forced"
|
||||||
},
|
},
|
||||||
|
"http2_support": {
|
||||||
|
"$ref": "#/definitions/http2_support"
|
||||||
|
},
|
||||||
"block_exploits": {
|
"block_exploits": {
|
||||||
"$ref": "#/definitions/block_exploits"
|
"$ref": "#/definitions/block_exploits"
|
||||||
},
|
},
|
||||||
"caching_enabled": {
|
"caching_enabled": {
|
||||||
"$ref": "#/definitions/caching_enabled"
|
"$ref": "#/definitions/caching_enabled"
|
||||||
},
|
},
|
||||||
|
"allow_websocket_upgrade": {
|
||||||
|
"$ref": "#/definitions/allow_websocket_upgrade"
|
||||||
|
},
|
||||||
"access_list_id": {
|
"access_list_id": {
|
||||||
"$ref": "#/definitions/access_list_id"
|
"$ref": "#/definitions/access_list_id"
|
||||||
},
|
},
|
||||||
@ -123,15 +145,19 @@
|
|||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"required": [
|
"required": [
|
||||||
"domain_names",
|
"domain_names",
|
||||||
"forward_ip",
|
"forward_scheme",
|
||||||
|
"forward_host",
|
||||||
"forward_port"
|
"forward_port"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"domain_names": {
|
"domain_names": {
|
||||||
"$ref": "#/definitions/domain_names"
|
"$ref": "#/definitions/domain_names"
|
||||||
},
|
},
|
||||||
"forward_ip": {
|
"forward_scheme": {
|
||||||
"$ref": "#/definitions/forward_ip"
|
"$ref": "#/definitions/forward_scheme"
|
||||||
|
},
|
||||||
|
"forward_host": {
|
||||||
|
"$ref": "#/definitions/forward_host"
|
||||||
},
|
},
|
||||||
"forward_port": {
|
"forward_port": {
|
||||||
"$ref": "#/definitions/forward_port"
|
"$ref": "#/definitions/forward_port"
|
||||||
@ -142,12 +168,18 @@
|
|||||||
"ssl_forced": {
|
"ssl_forced": {
|
||||||
"$ref": "#/definitions/ssl_forced"
|
"$ref": "#/definitions/ssl_forced"
|
||||||
},
|
},
|
||||||
|
"http2_support": {
|
||||||
|
"$ref": "#/definitions/http2_support"
|
||||||
|
},
|
||||||
"block_exploits": {
|
"block_exploits": {
|
||||||
"$ref": "#/definitions/block_exploits"
|
"$ref": "#/definitions/block_exploits"
|
||||||
},
|
},
|
||||||
"caching_enabled": {
|
"caching_enabled": {
|
||||||
"$ref": "#/definitions/caching_enabled"
|
"$ref": "#/definitions/caching_enabled"
|
||||||
},
|
},
|
||||||
|
"allow_websocket_upgrade": {
|
||||||
|
"$ref": "#/definitions/allow_websocket_upgrade"
|
||||||
|
},
|
||||||
"access_list_id": {
|
"access_list_id": {
|
||||||
"$ref": "#/definitions/access_list_id"
|
"$ref": "#/definitions/access_list_id"
|
||||||
},
|
},
|
||||||
@ -182,8 +214,11 @@
|
|||||||
"domain_names": {
|
"domain_names": {
|
||||||
"$ref": "#/definitions/domain_names"
|
"$ref": "#/definitions/domain_names"
|
||||||
},
|
},
|
||||||
"forward_ip": {
|
"forward_scheme": {
|
||||||
"$ref": "#/definitions/forward_ip"
|
"$ref": "#/definitions/forward_scheme"
|
||||||
|
},
|
||||||
|
"forward_host": {
|
||||||
|
"$ref": "#/definitions/forward_host"
|
||||||
},
|
},
|
||||||
"forward_port": {
|
"forward_port": {
|
||||||
"$ref": "#/definitions/forward_port"
|
"$ref": "#/definitions/forward_port"
|
||||||
@ -194,12 +229,18 @@
|
|||||||
"ssl_forced": {
|
"ssl_forced": {
|
||||||
"$ref": "#/definitions/ssl_forced"
|
"$ref": "#/definitions/ssl_forced"
|
||||||
},
|
},
|
||||||
|
"http2_support": {
|
||||||
|
"$ref": "#/definitions/http2_support"
|
||||||
|
},
|
||||||
"block_exploits": {
|
"block_exploits": {
|
||||||
"$ref": "#/definitions/block_exploits"
|
"$ref": "#/definitions/block_exploits"
|
||||||
},
|
},
|
||||||
"caching_enabled": {
|
"caching_enabled": {
|
||||||
"$ref": "#/definitions/caching_enabled"
|
"$ref": "#/definitions/caching_enabled"
|
||||||
},
|
},
|
||||||
|
"allow_websocket_upgrade": {
|
||||||
|
"$ref": "#/definitions/allow_websocket_upgrade"
|
||||||
|
},
|
||||||
"access_list_id": {
|
"access_list_id": {
|
||||||
"$ref": "#/definitions/access_list_id"
|
"$ref": "#/definitions/access_list_id"
|
||||||
},
|
},
|
||||||
|
@ -32,6 +32,9 @@
|
|||||||
"ssl_forced": {
|
"ssl_forced": {
|
||||||
"$ref": "../definitions.json#/definitions/ssl_forced"
|
"$ref": "../definitions.json#/definitions/ssl_forced"
|
||||||
},
|
},
|
||||||
|
"http2_support": {
|
||||||
|
"$ref": "../definitions.json#/definitions/http2_support"
|
||||||
|
},
|
||||||
"block_exploits": {
|
"block_exploits": {
|
||||||
"$ref": "../definitions.json#/definitions/block_exploits"
|
"$ref": "../definitions.json#/definitions/block_exploits"
|
||||||
},
|
},
|
||||||
@ -67,6 +70,9 @@
|
|||||||
"ssl_forced": {
|
"ssl_forced": {
|
||||||
"$ref": "#/definitions/ssl_forced"
|
"$ref": "#/definitions/ssl_forced"
|
||||||
},
|
},
|
||||||
|
"http2_support": {
|
||||||
|
"$ref": "#/definitions/http2_support"
|
||||||
|
},
|
||||||
"block_exploits": {
|
"block_exploits": {
|
||||||
"$ref": "#/definitions/block_exploits"
|
"$ref": "#/definitions/block_exploits"
|
||||||
},
|
},
|
||||||
@ -128,6 +134,9 @@
|
|||||||
"ssl_forced": {
|
"ssl_forced": {
|
||||||
"$ref": "#/definitions/ssl_forced"
|
"$ref": "#/definitions/ssl_forced"
|
||||||
},
|
},
|
||||||
|
"http2_support": {
|
||||||
|
"$ref": "#/definitions/http2_support"
|
||||||
|
},
|
||||||
"block_exploits": {
|
"block_exploits": {
|
||||||
"$ref": "#/definitions/block_exploits"
|
"$ref": "#/definitions/block_exploits"
|
||||||
},
|
},
|
||||||
@ -174,6 +183,9 @@
|
|||||||
"ssl_forced": {
|
"ssl_forced": {
|
||||||
"$ref": "#/definitions/ssl_forced"
|
"$ref": "#/definitions/ssl_forced"
|
||||||
},
|
},
|
||||||
|
"http2_support": {
|
||||||
|
"$ref": "#/definitions/http2_support"
|
||||||
|
},
|
||||||
"block_exploits": {
|
"block_exploits": {
|
||||||
"$ref": "#/definitions/block_exploits"
|
"$ref": "#/definitions/block_exploits"
|
||||||
},
|
},
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const NodeRSA = require('node-rsa');
|
const NodeRSA = require('node-rsa');
|
||||||
const config = require('config');
|
const config = require('config');
|
||||||
const logger = require('./logger').global;
|
const logger = require('./logger').setup;
|
||||||
const userModel = require('./models/user');
|
const userModel = require('./models/user');
|
||||||
const userPermissionModel = require('./models/user_permission');
|
const userPermissionModel = require('./models/user_permission');
|
||||||
const authModel = require('./models/auth');
|
const authModel = require('./models/auth');
|
||||||
|
const debug_mode = process.env.NODE_ENV !== 'production';
|
||||||
|
|
||||||
module.exports = function () {
|
module.exports = function () {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -22,6 +23,9 @@ module.exports = function () {
|
|||||||
config_data = require(filename);
|
config_data = require(filename);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
if (debug_mode) {
|
||||||
|
logger.debug(filename + ' config file could not be required');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now create the keys and save them in the config.
|
// Now create the keys and save them in the config.
|
||||||
@ -40,12 +44,18 @@ module.exports = function () {
|
|||||||
reject(err);
|
reject(err);
|
||||||
} else {
|
} else {
|
||||||
logger.info('Wrote JWT key pair to config file: ' + filename);
|
logger.info('Wrote JWT key pair to config file: ' + filename);
|
||||||
config.util.loadFileConfigs();
|
|
||||||
resolve();
|
logger.warn('Restarting interface to apply new configuration');
|
||||||
|
process.exit(0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// JWT key pair exists
|
// JWT key pair exists
|
||||||
|
if (debug_mode) {
|
||||||
|
logger.debug('JWT Keypair already exists');
|
||||||
|
}
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -54,7 +64,8 @@ module.exports = function () {
|
|||||||
.query()
|
.query()
|
||||||
.select(userModel.raw('COUNT(`id`) as `count`'))
|
.select(userModel.raw('COUNT(`id`) as `count`'))
|
||||||
.where('is_deleted', 0)
|
.where('is_deleted', 0)
|
||||||
.first('count')
|
.first();
|
||||||
|
})
|
||||||
.then(row => {
|
.then(row => {
|
||||||
if (!row.count) {
|
if (!row.count) {
|
||||||
// Create a new user and set password
|
// Create a new user and set password
|
||||||
@ -95,8 +106,12 @@ module.exports = function () {
|
|||||||
certificates: 'manage'
|
certificates: 'manage'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
logger.info('Initial setup completed');
|
||||||
});
|
});
|
||||||
|
} else if (debug_mode) {
|
||||||
|
logger.debug('Admin user setup not required');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
listen 80;
|
listen 80;
|
||||||
{% if certificate -%}
|
{% if certificate -%}
|
||||||
listen 443 ssl;
|
listen 443 ssl{% if http2_support %} http2{% endif %};
|
||||||
{% endif %}
|
{% endif %}
|
||||||
server_name {{ domain_names | join: " " }};
|
server_name {{ domain_names | join: " " }};
|
@ -1,7 +1,8 @@
|
|||||||
{% include "_header_comment.conf" %}
|
{% include "_header_comment.conf" %}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
set $server {{ forward_ip }};
|
set $forward_scheme {{ forward_scheme }};
|
||||||
|
set $server "{{ forward_host }}";
|
||||||
set $port {{ forward_port }};
|
set $port {{ forward_port }};
|
||||||
|
|
||||||
{% include "_listen.conf" %}
|
{% include "_listen.conf" %}
|
||||||
@ -22,6 +23,12 @@ server {
|
|||||||
|
|
||||||
{% include "_forced_ssl.conf" %}
|
{% include "_forced_ssl.conf" %}
|
||||||
|
|
||||||
|
{% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %}
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
# Proxy!
|
# Proxy!
|
||||||
include conf.d/include/proxy.conf;
|
include conf.d/include/proxy.conf;
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,9 @@ server {
|
|||||||
{% include "_forced_ssl.conf" %}
|
{% include "_forced_ssl.conf" %}
|
||||||
|
|
||||||
{% if preserve_path == 1 or preserve_path == true %}
|
{% if preserve_path == 1 or preserve_path == true %}
|
||||||
return 301 $scheme://{{ forward_domain_name }}$request_uri$request_uri;
|
|
||||||
{% else %}
|
|
||||||
return 301 $scheme://{{ forward_domain_name }}$request_uri;
|
return 301 $scheme://{{ forward_domain_name }}$request_uri;
|
||||||
|
{% else %}
|
||||||
|
return 301 $scheme://{{ forward_domain_name }};
|
||||||
{% endif %}
|
{% endif %}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,5 +5,5 @@
|
|||||||
<span class="loader"></span>
|
<span class="loader"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript" src="/js/main.js?v=<%= version %>"></script>
|
<script type="text/javascript" src="/js/main.bundle.js?v=<%= version %>"></script>
|
||||||
<%- include partials/footer.ejs %>
|
<%- include partials/footer.ejs %>
|
||||||
|
@ -5,5 +5,5 @@
|
|||||||
<span class="loader"></span>
|
<span class="loader"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript" src="/js/login.js?v=<%= version %>"></script>
|
<script type="text/javascript" src="/js/login.bundle.js?v=<%= version %>"></script>
|
||||||
<%- include partials/footer.ejs %>
|
<%- include partials/footer.ejs %>
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12 col-md-12">
|
<div class="col-sm-6 col-md-6">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="custom-switch">
|
<label class="custom-switch">
|
||||||
<input type="checkbox" class="custom-switch-input" name="ssl_forced" value="1"<%- ssl_forced ? ' checked' : '' %><%- certificate_id ? '' : ' disabled' %>>
|
<input type="checkbox" class="custom-switch-input" name="ssl_forced" value="1"<%- ssl_forced ? ' checked' : '' %><%- certificate_id ? '' : ' disabled' %>>
|
||||||
@ -45,6 +45,15 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-sm-6 col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="custom-switch">
|
||||||
|
<input type="checkbox" class="custom-switch-input" name="http2_support" value="1"<%- http2_support ? ' checked' : '' %><%- certificate_id ? '' : ' disabled' %>>
|
||||||
|
<span class="custom-switch-indicator"></span>
|
||||||
|
<span class="custom-switch-description"><%- i18n('all-hosts', 'http2-support') %></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Lets encrypt -->
|
<!-- Lets encrypt -->
|
||||||
<div class="col-sm-12 col-md-12 letsencrypt">
|
<div class="col-sm-12 col-md-12 letsencrypt">
|
||||||
|
@ -22,6 +22,7 @@ module.exports = Mn.View.extend({
|
|||||||
save: 'button.save',
|
save: 'button.save',
|
||||||
certificate_select: 'select[name="certificate_id"]',
|
certificate_select: 'select[name="certificate_id"]',
|
||||||
ssl_forced: 'input[name="ssl_forced"]',
|
ssl_forced: 'input[name="ssl_forced"]',
|
||||||
|
http2_support: 'input[name="http2_support"]',
|
||||||
letsencrypt: '.letsencrypt'
|
letsencrypt: '.letsencrypt'
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -35,7 +36,11 @@ module.exports = Mn.View.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
let enabled = id === 'new' || parseInt(id, 10) > 0;
|
let enabled = id === 'new' || parseInt(id, 10) > 0;
|
||||||
this.ui.ssl_forced.prop('disabled', !enabled).parents('.form-group').css('opacity', enabled ? 1 : 0.5);
|
this.ui.ssl_forced.add(this.ui.http2_support)
|
||||||
|
.prop('disabled', !enabled)
|
||||||
|
.parents('.form-group')
|
||||||
|
.css('opacity', enabled ? 1 : 0.5);
|
||||||
|
this.ui.http2_support.prop('disabled', !enabled);
|
||||||
},
|
},
|
||||||
|
|
||||||
'click @ui.save': function (e) {
|
'click @ui.save': function (e) {
|
||||||
@ -54,6 +59,10 @@ module.exports = Mn.View.extend({
|
|||||||
data.ssl_forced = true;
|
data.ssl_forced = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof data.http2_support !== 'undefined') {
|
||||||
|
data.http2_support = !!data.http2_support;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof data.domain_names === 'string' && data.domain_names) {
|
if (typeof data.domain_names === 'string' && data.domain_names) {
|
||||||
data.domain_names = data.domain_names.split(',');
|
data.domain_names = data.domain_names.split(',');
|
||||||
}
|
}
|
||||||
@ -74,7 +83,7 @@ module.exports = Mn.View.extend({
|
|||||||
|
|
||||||
data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';
|
data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';
|
||||||
} else {
|
} else {
|
||||||
data.certificate_id = parseInt(data.certificate_id, 0);
|
data.certificate_id = parseInt(data.certificate_id, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
let method = App.Api.Nginx.DeadHosts.create;
|
let method = App.Api.Nginx.DeadHosts.create;
|
||||||
|
@ -6,9 +6,15 @@
|
|||||||
<td>
|
<td>
|
||||||
<div>
|
<div>
|
||||||
<% domain_names.map(function(host) {
|
<% domain_names.map(function(host) {
|
||||||
|
if (host.indexOf('*') === -1) {
|
||||||
|
%>
|
||||||
|
<span class="tag host-link hover-red" rel="http<%- certificate_id ? 's' : '' %>://<%- host %>"><%- host %></span>
|
||||||
|
<%
|
||||||
|
} else {
|
||||||
%>
|
%>
|
||||||
<span class="tag"><%- host %></span>
|
<span class="tag"><%- host %></span>
|
||||||
<%
|
<%
|
||||||
|
}
|
||||||
});
|
});
|
||||||
%>
|
%>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,7 +10,8 @@ module.exports = Mn.View.extend({
|
|||||||
|
|
||||||
ui: {
|
ui: {
|
||||||
edit: 'a.edit',
|
edit: 'a.edit',
|
||||||
delete: 'a.delete'
|
delete: 'a.delete',
|
||||||
|
host_link: '.host-link'
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
@ -22,6 +23,12 @@ module.exports = Mn.View.extend({
|
|||||||
'click @ui.delete': function (e) {
|
'click @ui.delete': function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
App.Controller.showNginxDeadDeleteConfirm(this.model);
|
App.Controller.showNginxDeadDeleteConfirm(this.model);
|
||||||
|
},
|
||||||
|
|
||||||
|
'click @ui.host_link': function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
let win = window.open($(e.currentTarget).attr('rel'), '_blank');
|
||||||
|
win.focus();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -20,10 +20,19 @@
|
|||||||
<input type="text" name="domain_names" class="form-control" id="input-domains" value="<%- domain_names.join(',') %>" required>
|
<input type="text" name="domain_names" class="form-control" id="input-domains" value="<%- domain_names.join(',') %>" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-8 col-md-8">
|
<div class="col-sm-3 col-md-3">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label"><%- i18n('proxy-hosts', 'forward-ip') %><span class="form-required">*</span></label>
|
<label class="form-label"><%- i18n('proxy-hosts', 'forward-scheme') %><span class="form-required">*</span></label>
|
||||||
<input type="text" name="forward_ip" class="form-control text-monospace" placeholder="000.000.000.000" value="<%- forward_ip %>" autocomplete="off" maxlength="15" required>
|
<select name="forward_scheme" class="form-control custom-select" placeholder="http">
|
||||||
|
<option value="http" <%- forward_scheme === 'http' ? 'selected' : '' %>>http</option>
|
||||||
|
<option value="https" <%- forward_scheme === 'https' ? 'selected' : '' %>>https</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-5 col-md-5">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label"><%- i18n('proxy-hosts', 'forward-host') %><span class="form-required">*</span></label>
|
||||||
|
<input type="text" name="forward_host" class="form-control text-monospace" placeholder="" value="<%- forward_host %>" autocomplete="off" maxlength="50" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4 col-md-4">
|
<div class="col-sm-4 col-md-4">
|
||||||
@ -50,6 +59,16 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="custom-switch">
|
||||||
|
<input type="checkbox" class="custom-switch-input" name="allow_websocket_upgrade" value="1"<%- allow_websocket_upgrade ? ' checked' : '' %>>
|
||||||
|
<span class="custom-switch-indicator"></span>
|
||||||
|
<span class="custom-switch-description"><%- i18n('proxy-hosts', 'allow-websocket-upgrade') %></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-12 col-md-12">
|
<div class="col-sm-12 col-md-12">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label"><%- i18n('proxy-hosts', 'access-list') %></label>
|
<label class="form-label"><%- i18n('proxy-hosts', 'access-list') %></label>
|
||||||
@ -73,7 +92,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12 col-md-12">
|
<div class="col-sm-6 col-md-6">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="custom-switch">
|
<label class="custom-switch">
|
||||||
<input type="checkbox" class="custom-switch-input" name="ssl_forced" value="1"<%- ssl_forced ? ' checked' : '' %><%- certificate_id ? '' : ' disabled' %>>
|
<input type="checkbox" class="custom-switch-input" name="ssl_forced" value="1"<%- ssl_forced ? ' checked' : '' %><%- certificate_id ? '' : ' disabled' %>>
|
||||||
@ -82,6 +101,15 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-sm-6 col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="custom-switch">
|
||||||
|
<input type="checkbox" class="custom-switch-input" name="http2_support" value="1"<%- http2_support ? ' checked' : '' %><%- certificate_id ? '' : ' disabled' %>>
|
||||||
|
<span class="custom-switch-indicator"></span>
|
||||||
|
<span class="custom-switch-description"><%- i18n('all-hosts', 'http2-support') %></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Lets encrypt -->
|
<!-- Lets encrypt -->
|
||||||
<div class="col-sm-12 col-md-12 letsencrypt">
|
<div class="col-sm-12 col-md-12 letsencrypt">
|
||||||
|
@ -9,7 +9,6 @@ const accessListItemTemplate = require('./access-list-item.ejs');
|
|||||||
const Helpers = require('../../../lib/helpers');
|
const Helpers = require('../../../lib/helpers');
|
||||||
|
|
||||||
require('jquery-serializejson');
|
require('jquery-serializejson');
|
||||||
require('jquery-mask-plugin');
|
|
||||||
require('selectize');
|
require('selectize');
|
||||||
|
|
||||||
module.exports = Mn.View.extend({
|
module.exports = Mn.View.extend({
|
||||||
@ -19,13 +18,15 @@ module.exports = Mn.View.extend({
|
|||||||
ui: {
|
ui: {
|
||||||
form: 'form',
|
form: 'form',
|
||||||
domain_names: 'input[name="domain_names"]',
|
domain_names: 'input[name="domain_names"]',
|
||||||
forward_ip: 'input[name="forward_ip"]',
|
forward_host: 'input[name="forward_host"]',
|
||||||
buttons: '.modal-footer button',
|
buttons: '.modal-footer button',
|
||||||
cancel: 'button.cancel',
|
cancel: 'button.cancel',
|
||||||
save: 'button.save',
|
save: 'button.save',
|
||||||
certificate_select: 'select[name="certificate_id"]',
|
certificate_select: 'select[name="certificate_id"]',
|
||||||
access_list_select: 'select[name="access_list_id"]',
|
access_list_select: 'select[name="access_list_id"]',
|
||||||
ssl_forced: 'input[name="ssl_forced"]',
|
ssl_forced: 'input[name="ssl_forced"]',
|
||||||
|
http2_support: 'input[name="http2_support"]',
|
||||||
|
forward_scheme: 'select[name="forward_scheme"]',
|
||||||
letsencrypt: '.letsencrypt'
|
letsencrypt: '.letsencrypt'
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -39,7 +40,10 @@ module.exports = Mn.View.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
let enabled = id === 'new' || parseInt(id, 10) > 0;
|
let enabled = id === 'new' || parseInt(id, 10) > 0;
|
||||||
this.ui.ssl_forced.prop('disabled', !enabled).parents('.form-group').css('opacity', enabled ? 1 : 0.5);
|
this.ui.ssl_forced.add(this.ui.http2_support)
|
||||||
|
.prop('disabled', !enabled)
|
||||||
|
.parents('.form-group')
|
||||||
|
.css('opacity', enabled ? 1 : 0.5);
|
||||||
},
|
},
|
||||||
|
|
||||||
'click @ui.save': function (e) {
|
'click @ui.save': function (e) {
|
||||||
@ -57,11 +61,16 @@ module.exports = Mn.View.extend({
|
|||||||
data.forward_port = parseInt(data.forward_port, 10);
|
data.forward_port = parseInt(data.forward_port, 10);
|
||||||
data.block_exploits = !!data.block_exploits;
|
data.block_exploits = !!data.block_exploits;
|
||||||
data.caching_enabled = !!data.caching_enabled;
|
data.caching_enabled = !!data.caching_enabled;
|
||||||
|
data.allow_websocket_upgrade = !!data.allow_websocket_upgrade;
|
||||||
|
|
||||||
if (typeof data.ssl_forced !== 'undefined' && data.ssl_forced === '1') {
|
if (typeof data.ssl_forced !== 'undefined' && data.ssl_forced === '1') {
|
||||||
data.ssl_forced = true;
|
data.ssl_forced = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof data.http2_support !== 'undefined') {
|
||||||
|
data.http2_support = !!data.http2_support;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof data.domain_names === 'string' && data.domain_names) {
|
if (typeof data.domain_names === 'string' && data.domain_names) {
|
||||||
data.domain_names = data.domain_names.split(',');
|
data.domain_names = data.domain_names.split(',');
|
||||||
}
|
}
|
||||||
@ -82,7 +91,7 @@ module.exports = Mn.View.extend({
|
|||||||
|
|
||||||
data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';
|
data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';
|
||||||
} else {
|
} else {
|
||||||
data.certificate_id = parseInt(data.certificate_id, 0);
|
data.certificate_id = parseInt(data.certificate_id, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
let method = App.Api.Nginx.ProxyHosts.create;
|
let method = App.Api.Nginx.ProxyHosts.create;
|
||||||
@ -122,12 +131,6 @@ module.exports = Mn.View.extend({
|
|||||||
onRender: function () {
|
onRender: function () {
|
||||||
let view = this;
|
let view = this;
|
||||||
|
|
||||||
// IP Address
|
|
||||||
this.ui.forward_ip.mask('099.099.099.099', {
|
|
||||||
clearIfNotMatch: true,
|
|
||||||
placeholder: '000.000.000.000'
|
|
||||||
});
|
|
||||||
|
|
||||||
// Domain names
|
// Domain names
|
||||||
this.ui.domain_names.selectize({
|
this.ui.domain_names.selectize({
|
||||||
delimiter: ',',
|
delimiter: ',',
|
||||||
@ -143,7 +146,6 @@ module.exports = Mn.View.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Access Lists
|
// Access Lists
|
||||||
this.ui.letsencrypt.hide();
|
|
||||||
this.ui.access_list_select.selectize({
|
this.ui.access_list_select.selectize({
|
||||||
valueField: 'id',
|
valueField: 'id',
|
||||||
labelField: 'name',
|
labelField: 'name',
|
||||||
|
@ -6,9 +6,15 @@
|
|||||||
<td>
|
<td>
|
||||||
<div>
|
<div>
|
||||||
<% domain_names.map(function(host) {
|
<% domain_names.map(function(host) {
|
||||||
|
if (host.indexOf('*') === -1) {
|
||||||
|
%>
|
||||||
|
<span class="tag host-link hover-green" rel="http<%- certificate_id ? 's' : '' %>://<%- host %>"><%- host %></span>
|
||||||
|
<%
|
||||||
|
} else {
|
||||||
%>
|
%>
|
||||||
<span class="tag"><%- host %></span>
|
<span class="tag"><%- host %></span>
|
||||||
<%
|
<%
|
||||||
|
}
|
||||||
});
|
});
|
||||||
%>
|
%>
|
||||||
</div>
|
</div>
|
||||||
@ -17,7 +23,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="text-monospace"><%- forward_ip %>:<%- forward_port %></div>
|
<div class="text-monospace"><%- forward_scheme %>://<%- forward_host %>:<%- forward_port %></div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div><%- certificate && certificate_id ? i18n('ssl', certificate.provider) : i18n('ssl', 'none') %></div>
|
<div><%- certificate && certificate_id ? i18n('ssl', certificate.provider) : i18n('ssl', 'none') %></div>
|
||||||
|
@ -10,7 +10,8 @@ module.exports = Mn.View.extend({
|
|||||||
|
|
||||||
ui: {
|
ui: {
|
||||||
edit: 'a.edit',
|
edit: 'a.edit',
|
||||||
delete: 'a.delete'
|
delete: 'a.delete',
|
||||||
|
host_link: '.host-link'
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
@ -22,6 +23,12 @@ module.exports = Mn.View.extend({
|
|||||||
'click @ui.delete': function (e) {
|
'click @ui.delete': function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
App.Controller.showNginxProxyDeleteConfirm(this.model);
|
App.Controller.showNginxProxyDeleteConfirm(this.model);
|
||||||
|
},
|
||||||
|
|
||||||
|
'click @ui.host_link': function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
let win = window.open($(e.currentTarget).attr('rel'), '_blank');
|
||||||
|
win.focus();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12 col-md-12">
|
<div class="col-sm-6 col-md-6">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="custom-switch">
|
<label class="custom-switch">
|
||||||
<input type="checkbox" class="custom-switch-input" name="ssl_forced" value="1"<%- ssl_forced ? ' checked' : '' %><%- certificate_id ? '' : ' disabled' %>>
|
<input type="checkbox" class="custom-switch-input" name="ssl_forced" value="1"<%- ssl_forced ? ' checked' : '' %><%- certificate_id ? '' : ' disabled' %>>
|
||||||
@ -69,6 +69,15 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-sm-6 col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="custom-switch">
|
||||||
|
<input type="checkbox" class="custom-switch-input" name="http2_support" value="1"<%- http2_support ? ' checked' : '' %><%- certificate_id ? '' : ' disabled' %>>
|
||||||
|
<span class="custom-switch-indicator"></span>
|
||||||
|
<span class="custom-switch-description"><%- i18n('all-hosts', 'http2-support') %></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Lets encrypt -->
|
<!-- Lets encrypt -->
|
||||||
<div class="col-sm-12 col-md-12 letsencrypt">
|
<div class="col-sm-12 col-md-12 letsencrypt">
|
||||||
|
@ -22,6 +22,7 @@ module.exports = Mn.View.extend({
|
|||||||
save: 'button.save',
|
save: 'button.save',
|
||||||
certificate_select: 'select[name="certificate_id"]',
|
certificate_select: 'select[name="certificate_id"]',
|
||||||
ssl_forced: 'input[name="ssl_forced"]',
|
ssl_forced: 'input[name="ssl_forced"]',
|
||||||
|
http2_support: 'input[name="http2_support"]',
|
||||||
letsencrypt: '.letsencrypt'
|
letsencrypt: '.letsencrypt'
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -35,7 +36,11 @@ module.exports = Mn.View.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
let enabled = id === 'new' || parseInt(id, 10) > 0;
|
let enabled = id === 'new' || parseInt(id, 10) > 0;
|
||||||
this.ui.ssl_forced.prop('disabled', !enabled).parents('.form-group').css('opacity', enabled ? 1 : 0.5);
|
this.ui.ssl_forced.add(this.ui.http2_support)
|
||||||
|
.prop('disabled', !enabled)
|
||||||
|
.parents('.form-group')
|
||||||
|
.css('opacity', enabled ? 1 : 0.5);
|
||||||
|
this.ui.http2_support.prop('disabled', !enabled);
|
||||||
},
|
},
|
||||||
|
|
||||||
'click @ui.save': function (e) {
|
'click @ui.save': function (e) {
|
||||||
@ -57,6 +62,10 @@ module.exports = Mn.View.extend({
|
|||||||
data.ssl_forced = true;
|
data.ssl_forced = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof data.http2_support !== 'undefined') {
|
||||||
|
data.http2_support = !!data.http2_support;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof data.domain_names === 'string' && data.domain_names) {
|
if (typeof data.domain_names === 'string' && data.domain_names) {
|
||||||
data.domain_names = data.domain_names.split(',');
|
data.domain_names = data.domain_names.split(',');
|
||||||
}
|
}
|
||||||
@ -77,7 +86,7 @@ module.exports = Mn.View.extend({
|
|||||||
|
|
||||||
data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';
|
data.meta.letsencrypt_agree = data.meta.letsencrypt_agree === '1';
|
||||||
} else {
|
} else {
|
||||||
data.certificate_id = parseInt(data.certificate_id, 0);
|
data.certificate_id = parseInt(data.certificate_id, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
let method = App.Api.Nginx.RedirectionHosts.create;
|
let method = App.Api.Nginx.RedirectionHosts.create;
|
||||||
|
@ -6,9 +6,15 @@
|
|||||||
<td>
|
<td>
|
||||||
<div>
|
<div>
|
||||||
<% domain_names.map(function(host) {
|
<% domain_names.map(function(host) {
|
||||||
|
if (host.indexOf('*') === -1) {
|
||||||
|
%>
|
||||||
|
<span class="tag host-link hover-yellow" rel="http<%- certificate_id ? 's' : '' %>://<%- host %>"><%- host %></span>
|
||||||
|
<%
|
||||||
|
} else {
|
||||||
%>
|
%>
|
||||||
<span class="tag"><%- host %></span>
|
<span class="tag"><%- host %></span>
|
||||||
<%
|
<%
|
||||||
|
}
|
||||||
});
|
});
|
||||||
%>
|
%>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,7 +10,8 @@ module.exports = Mn.View.extend({
|
|||||||
|
|
||||||
ui: {
|
ui: {
|
||||||
edit: 'a.edit',
|
edit: 'a.edit',
|
||||||
delete: 'a.delete'
|
delete: 'a.delete',
|
||||||
|
host_link: '.host-link'
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
@ -22,6 +23,12 @@ module.exports = Mn.View.extend({
|
|||||||
'click @ui.delete': function (e) {
|
'click @ui.delete': function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
App.Controller.showNginxRedirectionDeleteConfirm(this.model);
|
App.Controller.showNginxRedirectionDeleteConfirm(this.model);
|
||||||
|
},
|
||||||
|
|
||||||
|
'click @ui.host_link': function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
let win = window.open($(e.currentTarget).attr('rel'), '_blank');
|
||||||
|
win.focus();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
"details": "Details",
|
"details": "Details",
|
||||||
"enable-ssl": "Enable SSL",
|
"enable-ssl": "Enable SSL",
|
||||||
"force-ssl": "Force SSL",
|
"force-ssl": "Force SSL",
|
||||||
|
"http2-support": "HTTP/2 Support",
|
||||||
"domain-names": "Domain Names",
|
"domain-names": "Domain Names",
|
||||||
"cert-provider": "Certificate Provider",
|
"cert-provider": "Certificate Provider",
|
||||||
"block-exploits": "Block Common Exploits",
|
"block-exploits": "Block Common Exploits",
|
||||||
@ -92,13 +93,16 @@
|
|||||||
"empty": "There are no Proxy Hosts",
|
"empty": "There are no Proxy Hosts",
|
||||||
"add": "Add Proxy Host",
|
"add": "Add Proxy Host",
|
||||||
"form-title": "{id, select, undefined{New} other{Edit}} Proxy Host",
|
"form-title": "{id, select, undefined{New} other{Edit}} Proxy Host",
|
||||||
"forward-ip": "Forward IP",
|
"forward-scheme": "Scheme",
|
||||||
|
"forward-host": "Forward Hostname / IP",
|
||||||
"forward-port": "Forward Port",
|
"forward-port": "Forward Port",
|
||||||
"delete": "Delete Proxy Host",
|
"delete": "Delete Proxy Host",
|
||||||
"delete-confirm": "Are you sure you want to delete the Proxy host for: <strong>{domains}</strong>?",
|
"delete-confirm": "Are you sure you want to delete the Proxy host for: <strong>{domains}</strong>?",
|
||||||
"help-title": "What is a Proxy Host?",
|
"help-title": "What is a Proxy Host?",
|
||||||
"help-content": "A Proxy Host is the incoming endpoint for a web service that you want to forward.\nIt provides optional SSL termination for your service that might not have SSL support built in.\nProxy Hosts are the most common use for the Nginx Proxy Manager.",
|
"help-content": "A Proxy Host is the incoming endpoint for a web service that you want to forward.\nIt provides optional SSL termination for your service that might not have SSL support built in.\nProxy Hosts are the most common use for the Nginx Proxy Manager.",
|
||||||
"access-list": "Access List"
|
"access-list": "Access List",
|
||||||
|
"allow-websocket-upgrade": "Websockets Support",
|
||||||
|
"ignore-invalid-upstream-ssl": "Ignore Invalid SSL"
|
||||||
},
|
},
|
||||||
"redirection-hosts": {
|
"redirection-hosts": {
|
||||||
"title": "Redirection Hosts",
|
"title": "Redirection Hosts",
|
||||||
|
@ -13,6 +13,7 @@ const model = Backbone.Model.extend({
|
|||||||
domain_names: [],
|
domain_names: [],
|
||||||
certificate_id: 0,
|
certificate_id: 0,
|
||||||
ssl_forced: false,
|
ssl_forced: false,
|
||||||
|
http2_support: false,
|
||||||
meta: {},
|
meta: {},
|
||||||
advanced_config: '',
|
advanced_config: '',
|
||||||
// The following are expansions:
|
// The following are expansions:
|
||||||
|
@ -11,13 +11,16 @@ const model = Backbone.Model.extend({
|
|||||||
created_on: null,
|
created_on: null,
|
||||||
modified_on: null,
|
modified_on: null,
|
||||||
domain_names: [],
|
domain_names: [],
|
||||||
forward_ip: '',
|
forward_scheme: 'http',
|
||||||
|
forward_host: '',
|
||||||
forward_port: null,
|
forward_port: null,
|
||||||
access_list_id: 0,
|
access_list_id: 0,
|
||||||
certificate_id: 0,
|
certificate_id: 0,
|
||||||
ssl_forced: false,
|
ssl_forced: false,
|
||||||
caching_enabled: false,
|
caching_enabled: false,
|
||||||
|
allow_websocket_upgrade: false,
|
||||||
block_exploits: false,
|
block_exploits: false,
|
||||||
|
http2_support: false,
|
||||||
advanced_config: '',
|
advanced_config: '',
|
||||||
meta: {},
|
meta: {},
|
||||||
// The following are expansions:
|
// The following are expansions:
|
||||||
|
@ -16,6 +16,7 @@ const model = Backbone.Model.extend({
|
|||||||
certificate_id: 0,
|
certificate_id: 0,
|
||||||
ssl_forced: false,
|
ssl_forced: false,
|
||||||
block_exploits: false,
|
block_exploits: false,
|
||||||
|
http2_support: false,
|
||||||
advanced_config: '',
|
advanced_config: '',
|
||||||
meta: {},
|
meta: {},
|
||||||
// The following are expansions:
|
// The following are expansions:
|
||||||
|
@ -3,6 +3,18 @@ $yellow: #f1c40f;
|
|||||||
$blue: #467fcf;
|
$blue: #467fcf;
|
||||||
$pink: #f66d9b;
|
$pink: #f66d9b;
|
||||||
|
|
||||||
|
.tag.hover-green:hover, .tag.hover-green:active, .tag.hover-green:focus {
|
||||||
|
background-color: #5eba00;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag.hover-red:hover, .tag.hover-red:active, .tag.hover-red:focus {
|
||||||
|
background-color: #cd201f;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
/* For Card bodies where I don't want padding */
|
/* For Card bodies where I don't want padding */
|
||||||
.card-body.no-padding {
|
.card-body.no-padding {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@ -28,6 +40,12 @@ $pink: #f66d9b;
|
|||||||
border-color: $teal;
|
border-color: $teal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tag.hover-teal:hover, .tag.hover-teal:active, .tag.hover-teal:focus {
|
||||||
|
background-color: $teal;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
/* Yellow Outline Buttons */
|
/* Yellow Outline Buttons */
|
||||||
.btn-outline-yellow {
|
.btn-outline-yellow {
|
||||||
color: $yellow;
|
color: $yellow;
|
||||||
@ -48,6 +66,12 @@ $pink: #f66d9b;
|
|||||||
border-color: $yellow;
|
border-color: $yellow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tag.hover-yellow:hover, .tag.hover-yellow:active, .tag.hover-yellow:focus {
|
||||||
|
background-color: $yellow;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
/* Blue Outline Buttons */
|
/* Blue Outline Buttons */
|
||||||
.btn-outline-blue {
|
.btn-outline-blue {
|
||||||
color: $blue;
|
color: $blue;
|
||||||
@ -68,6 +92,12 @@ $pink: #f66d9b;
|
|||||||
border-color: $blue;
|
border-color: $blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tag.hover-blue:hover, .tag.hover-blue:active, .tag.hover-blue:focus {
|
||||||
|
background-color: $blue;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
/* Pink Outline Buttons */
|
/* Pink Outline Buttons */
|
||||||
.btn-outline-pink {
|
.btn-outline-pink {
|
||||||
color: $pink;
|
color: $pink;
|
||||||
@ -88,6 +118,11 @@ $pink: #f66d9b;
|
|||||||
border-color: $pink;
|
border-color: $pink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tag.hover-pink:hover, .tag.hover-pink:active, .tag.hover-pink:focus {
|
||||||
|
background-color: $pink;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
/* dimmer */
|
/* dimmer */
|
||||||
|
|
||||||
.dimmer .loader {
|
.dimmer .loader {
|
||||||
|
@ -11,7 +11,8 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, 'dist'),
|
path: path.resolve(__dirname, 'dist'),
|
||||||
filename: 'js/[name].js',
|
filename: 'js/[name].bundle.js',
|
||||||
|
chunkFilename: 'js/[name].bundle.[id].js',
|
||||||
publicPath: '/'
|
publicPath: '/'
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
@ -108,41 +109,6 @@ module.exports = {
|
|||||||
to: 'images',
|
to: 'images',
|
||||||
toType: 'dir',
|
toType: 'dir',
|
||||||
context: '/app'
|
context: '/app'
|
||||||
}]),
|
}])
|
||||||
new webpack.optimize.LimitChunkCountPlugin({
|
]
|
||||||
maxChunks: 1, // Must be greater than or equal to one
|
|
||||||
minChunkSize: 999999999
|
|
||||||
})
|
|
||||||
],
|
|
||||||
/*
|
|
||||||
optimization: {
|
|
||||||
splitChunks: {
|
|
||||||
chunks (chunk) {
|
|
||||||
// exclude `my-excluded-chunk`
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
minSize: 999999999,
|
|
||||||
minChunks: 1,
|
|
||||||
name: true,
|
|
||||||
cacheGroups: {
|
|
||||||
vendors: {
|
|
||||||
test: /[\\/]node_modules[\\/]/,
|
|
||||||
priority: -10
|
|
||||||
},
|
|
||||||
default: {
|
|
||||||
minChunks: 2,
|
|
||||||
priority: -20,
|
|
||||||
reuseExistingChunk: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
devServer: {
|
|
||||||
contentBase: path.join(__dirname, 'dist'),
|
|
||||||
compress: true,
|
|
||||||
port: 8080,
|
|
||||||
disableHostCheck: true,
|
|
||||||
host: '0.0.0.0'
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user