Compare commits

..

25 Commits

Author SHA1 Message Date
a72811ee25 Updated version in readme 2018-09-04 10:33:35 +10:00
ac9d9cdddd Fix SSL custom certificates being saved, nginx errors being reported and leaking custom certs in api calls 2018-09-04 10:33:09 +10:00
5ac0e3dc95 Bump version 2018-09-03 09:51:03 +10:00
bbe02bc70a Fixes #10 - Don't use defaults for json fields in migration 2018-09-03 09:50:18 +10:00
02b4def04a Fix #9 - Variable definition was incorrectly scoped 2018-09-03 09:21:12 +10:00
5dd723a864 Removed v1 cruft 2018-09-03 09:13:17 +10:00
d04f5a619a Updated dockerhub readme 2018-08-30 14:44:49 +10:00
6542f4c2fe Updated readme 2018-08-30 14:42:16 +10:00
32d6bf83c8 Merge branch 'v2' of github.com:jc21/nginx-proxy-manager 2018-08-30 14:32:46 +10:00
a4b918e648 Merge branch 'v2' of github.com:jc21/nginx-proxy-manager into v2 2018-08-27 17:00:06 +10:00
de367ae194 Fix redirection config bug 2018-08-27 16:59:05 +10:00
2226359cfe Added major docker image to CI 2018-08-24 21:29:31 +10:00
10e87d2e6f Updated README with armhf 2018-07-31 10:28:53 +10:00
5b58fb3bd2 Fix missing dir for armhf nginx build 2018-07-31 09:51:55 +10:00
968750a856 Merge branch 'master' of github.com:jc21/nginx-proxy-manager 2018-07-31 09:14:07 +10:00
673cfb0027 Updated CI 2018-07-31 09:09:20 +10:00
5b45312f17 Whoops, fix CI again 2018-07-30 13:52:41 +10:00
95d9e87f51 Update CI notifications 2018-07-30 12:47:52 +10:00
1382350d3a Fix CI 2018-07-30 12:33:26 +10:00
353eeaa0ae Fix CI 2018-07-30 12:06:23 +10:00
3dee0eba4e Upgraded to webpack4 2018-07-30 11:59:28 +10:00
2111d2913b Use commonjs requires instead of mixing imports/exports/requires 2018-07-30 11:59:05 +10:00
36b014aa47 Updated CI for armhf 2018-07-30 10:10:42 +10:00
e2c6aedbfa Updated CI for armhf 2018-07-30 10:06:08 +10:00
cb449a8f5d Armhf build attempt 2018-07-29 19:09:40 +10:00
23 changed files with 247 additions and 51 deletions

31
Jenkinsfile vendored
View File

@ -6,7 +6,7 @@ pipeline {
agent any
environment {
IMAGE_NAME = "nginx-proxy-manager"
BASE_IMAGE_NAME = "jc21/nginx-proxy-manager-base"
BASE_IMAGE_NAME = "jc21/nginx-proxy-manager-base:v2"
TEMP_IMAGE_NAME = "nginx-proxy-manager-build_${BUILD_NUMBER}"
TEMP_IMAGE_NAME_ARM = "nginx-proxy-manager-arm-build_${BUILD_NUMBER}"
TAG_VERSION = getPackageVersion()
@ -21,13 +21,16 @@ pipeline {
stage('Build') {
parallel {
stage('x86_64') {
when {
branch 'master'
}
steps {
ansiColor('xterm') {
// 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:latest npm run-script build'
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME yarn --registry=$NPM_REGISTRY 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:latest yarn --registry=$NPM_REGISTRY install --prod'
sh 'docker run --rm -v $(pwd):/app -w /app $BASE_IMAGE_NAME yarn --registry=$NPM_REGISTRY install --prod'
sh 'docker run --rm -v $(pwd):/data $DOCKER_CI_TOOLS node-prune'
// Docker Build
@ -38,15 +41,19 @@ pipeline {
sh 'docker push $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$TAG_VERSION'
sh 'docker tag $TEMP_IMAGE_NAME $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$MAJOR_VERSION'
sh 'docker push $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:$MAJOR_VERSION'
sh 'docker tag $TEMP_IMAGE_NAME $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:latest'
sh 'docker push $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:latest'
// 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:$MAJOR_VERSION'
sh 'docker tag $TEMP_IMAGE_NAME docker.io/jc21/$IMAGE_NAME:latest'
withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'dpass', usernameVariable: 'duser')]) {
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:$MAJOR_VERSION'
sh 'docker push docker.io/jc21/$IMAGE_NAME:latest'
}
sh 'docker rmi $TEMP_IMAGE_NAME'
@ -54,34 +61,41 @@ pipeline {
}
}
stage('armhf') {
when {
branch 'master'
}
agent {
label 'armhf'
}
steps {
ansiColor('xterm') {
// 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 npm run-script build'
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 npm run-script build'
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 --registry=$NPM_REGISTRY install --prod'
// 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'
sh 'docker tag $TEMP_IMAGE_NAME_ARM $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:latest-armhf'
sh 'docker push $DOCKER_PRIVATE_REGISTRY/$IMAGE_NAME:latest-armhf'
// 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:$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')]) {
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:$MAJOR_VERSION-armhf'
sh 'docker push docker.io/jc21/$IMAGE_NAME:latest-armhf'
}
sh 'docker rmi $TEMP_IMAGE_NAME_ARM'
@ -107,3 +121,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)
return ver.trim()
}

View File

@ -2,7 +2,7 @@
# Nginx Proxy Manager
![Version](https://img.shields.io/badge/version-2.0.0-green.svg?style=for-the-badge)
![Version](https://img.shields.io/badge/version-2.0.2-green.svg?style=for-the-badge)
![Stars](https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge)
![Pulls](https://img.shields.io/docker/pulls/jc21/nginx-proxy-manager.svg?style=for-the-badge)

View File

@ -14,16 +14,16 @@ running at home or otherwise, including free SSL, without having to know too muc
## Tags
* latest 1, 1.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))
* 2, 2.x.x ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/v2/Dockerfile))
* 2-armhf, 2.x.x-armhf ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/v2/Dockerfile.armhf))
* latest 2, 2.x.x ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/master/Dockerfile))
* latest-armhf, 2-armhf, 2.x.x-armhf ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/master/Dockerfile.armhf))
* 1, 1.x.x ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/1.1.2/Dockerfile))
* 1-armhf, 1.x.x-armhf ([Dockerfile](https://github.com/jc21/nginx-proxy-manager/blob/1.1.2/Dockerfile.armhf))
## Getting started
Please consult the [installation instructions](https://github.com/jc21/nginx-proxy-manager/blob/v2/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`
Please consult the [installation instructions](https://github.com/jc21/nginx-proxy-manager/blob/master/doc/INSTALL.md) for a complete guide or
if you just want to get up and running in the quickest time possible, grab all the files in the [doc/example/](https://github.com/jc21/nginx-proxy-manager/tree/master/doc/example) folder and run `docker-compose up -d`
## Screenshots

View File

@ -1,6 +1,6 @@
{
"name": "nginx-proxy-manager",
"version": "2.0.0",
"version": "2.0.2",
"description": "A beautiful interface for creating Nginx endpoints",
"main": "src/backend/index.js",
"devDependencies": {

View File

@ -183,10 +183,7 @@ const internalCertificate = {
});
});
} else {
return internalCertificate.writeCustomCert(certificate)
.then(() => {
return certificate;
});
return certificate;
}
}).then(certificate => {
@ -409,9 +406,13 @@ const internalCertificate = {
* @returns {Promise}
*/
writeCustomCert: certificate => {
return new Promise((resolve, reject) => {
let dir = '/data/custom_ssl/npm-' + certificate.id;
if (debug_mode) {
logger.info('Writing Custom Certificate:', certificate);
}
let dir = '/data/custom_ssl/npm-' + certificate.id;
return new Promise((resolve, reject) => {
if (certificate.provider === 'letsencrypt') {
reject(new Error('Refusing to write letsencrypt certs here'));
return;
@ -549,8 +550,13 @@ const internalCertificate = {
id: data.id,
expires_on: certificateModel.raw('FROM_UNIXTIME(' + validations.certificate.dates.to + ')'),
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(() => {
return _.pick(row.meta, internalCertificate.allowed_ssl_files);

View File

@ -189,7 +189,9 @@ const internalDeadHost = {
.then(row => {
// Configure nginx
return internalNginx.configure(deadHostModel, 'dead_host', row)
.then(() => {
.then(new_meta => {
row.meta = new_meta;
row = internalHost.cleanRowCertificateMeta(row);
return _.omit(row, omissions());
});
});
@ -235,6 +237,7 @@ const internalDeadHost = {
})
.then(row => {
if (row) {
row = internalHost.cleanRowCertificateMeta(row);
return _.omit(row, omissions());
} else {
throw new error.ItemNotFoundError(data.id);
@ -322,6 +325,13 @@ const internalDeadHost = {
}
return query;
})
.then(rows => {
if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) {
return internalHost.cleanAllRowsCertificateMeta(rows);
}
return rows;
});
},

View File

@ -6,6 +6,36 @@ const deadHostModel = require('../models/dead_host');
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 is used by the certificates to temporarily disable any host that is using the domain

View File

@ -25,6 +25,8 @@ const internalNginx = {
* @returns {Promise}
*/
configure: (model, host_type, host) => {
let combined_meta = {};
return internalNginx.test()
.then(() => {
// Nginx is OK
@ -39,30 +41,46 @@ const internalNginx = {
return internalNginx.test()
.then(() => {
// nginx is ok
combined_meta = _.assign({}, host.meta, {
nginx_online: true,
nginx_err: null
});
return model
.query()
.where('id', host.id)
.patch({
meta: _.assign({}, host.meta, {
nginx_online: true,
nginx_err: null
})
meta: combined_meta
});
})
.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) {
logger.error('Nginx test failed:', err.message);
logger.error('Nginx test failed:', valid_lines.join("\n"));
}
// config is bad, update meta and delete config
combined_meta = _.assign({}, host.meta, {
nginx_online: false,
nginx_err: valid_lines.join("\n")
});
return model
.query()
.where('id', host.id)
.patch({
meta: _.assign({}, host.meta, {
nginx_online: false,
nginx_err: err.message
})
meta: combined_meta
})
.then(() => {
return internalNginx.deleteConfig(host_type, host, true);
@ -71,7 +89,10 @@ const internalNginx = {
})
.then(() => {
return internalNginx.reload();
});
})
.then(() => {
return combined_meta;
})
},
/**
@ -82,7 +103,7 @@ const internalNginx = {
logger.info('Testing Nginx configuration');
}
return utils.exec('/usr/sbin/nginx -t');
return utils.exec('/usr/sbin/nginx -t -g "error_log off;"');
},
/**

View File

@ -190,7 +190,9 @@ const internalProxyHost = {
.then(row => {
// Configure nginx
return internalNginx.configure(proxyHostModel, 'proxy_host', row)
.then(() => {
.then(new_meta => {
row.meta = new_meta;
row = internalHost.cleanRowCertificateMeta(row);
return _.omit(row, omissions());
});
});
@ -236,6 +238,7 @@ const internalProxyHost = {
})
.then(row => {
if (row) {
row = internalHost.cleanRowCertificateMeta(row);
return _.omit(row, omissions());
} else {
throw new error.ItemNotFoundError(data.id);
@ -323,6 +326,13 @@ const internalProxyHost = {
}
return query;
})
.then(rows => {
if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) {
return internalHost.cleanAllRowsCertificateMeta(rows);
}
return rows;
});
},

View File

@ -189,7 +189,9 @@ const internalRedirectionHost = {
.then(row => {
// Configure nginx
return internalNginx.configure(redirectionHostModel, 'redirection_host', row)
.then(() => {
.then(new_meta => {
row.meta = new_meta;
row = internalHost.cleanRowCertificateMeta(row);
return _.omit(row, omissions());
});
});
@ -235,6 +237,7 @@ const internalRedirectionHost = {
})
.then(row => {
if (row) {
row = internalHost.cleanRowCertificateMeta(row);
return _.omit(row, omissions());
} else {
throw new error.ItemNotFoundError(data.id);
@ -322,6 +325,13 @@ const internalRedirectionHost = {
}
return query;
})
.then(rows => {
if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) {
return internalHost.cleanAllRowsCertificateMeta(rows);
}
return rows;
});
},

View File

@ -22,7 +22,7 @@ exports.up = function (knex/*, Promise*/) {
table.integer('user_id').notNull().unsigned();
table.string('type', 30).notNull();
table.string('secret').notNull();
table.json('meta').notNull().defaultTo('{}');
table.json('meta').notNull();
table.integer('is_deleted').notNull().unsigned().defaultTo(0);
})
.then(() => {
@ -77,7 +77,7 @@ exports.up = function (knex/*, Promise*/) {
table.integer('caching_enabled').notNull().unsigned().defaultTo(0);
table.integer('block_exploits').notNull().unsigned().defaultTo(0);
table.text('advanced_config').notNull().defaultTo('');
table.json('meta').notNull().defaultTo('{}');
table.json('meta').notNull();
});
})
.then(() => {
@ -96,7 +96,7 @@ exports.up = function (knex/*, Promise*/) {
table.integer('ssl_forced').notNull().unsigned().defaultTo(0);
table.integer('block_exploits').notNull().unsigned().defaultTo(0);
table.text('advanced_config').notNull().defaultTo('');
table.json('meta').notNull().defaultTo('{}');
table.json('meta').notNull();
});
})
.then(() => {
@ -112,7 +112,7 @@ exports.up = function (knex/*, Promise*/) {
table.integer('certificate_id').notNull().unsigned().defaultTo(0);
table.integer('ssl_forced').notNull().unsigned().defaultTo(0);
table.text('advanced_config').notNull().defaultTo('');
table.json('meta').notNull().defaultTo('{}');
table.json('meta').notNull();
});
})
.then(() => {
@ -129,7 +129,7 @@ exports.up = function (knex/*, Promise*/) {
table.integer('forwarding_port').notNull().unsigned();
table.integer('tcp_forwarding').notNull().unsigned().defaultTo(0);
table.integer('udp_forwarding').notNull().unsigned().defaultTo(0);
table.json('meta').notNull().defaultTo('{}');
table.json('meta').notNull();
});
})
.then(() => {
@ -142,7 +142,7 @@ exports.up = function (knex/*, Promise*/) {
table.integer('owner_user_id').notNull().unsigned();
table.integer('is_deleted').notNull().unsigned().defaultTo(0);
table.string('name').notNull();
table.json('meta').notNull().defaultTo('{}');
table.json('meta').notNull();
});
})
.then(() => {
@ -156,9 +156,9 @@ exports.up = function (knex/*, Promise*/) {
table.integer('is_deleted').notNull().unsigned().defaultTo(0);
table.string('provider').notNull();
table.string('nice_name').notNull().defaultTo('');
table.json('domain_names').notNull().defaultTo('[]');
table.json('domain_names').notNull();
table.dateTime('expires_on').notNull();
table.json('meta').notNull().defaultTo('{}');
table.json('meta').notNull();
});
})
.then(() => {
@ -171,7 +171,7 @@ exports.up = function (knex/*, Promise*/) {
table.integer('access_list_id').notNull().unsigned();
table.string('username').notNull();
table.string('password').notNull();
table.json('meta').notNull().defaultTo('{}');
table.json('meta').notNull();
});
})
.then(() => {
@ -185,7 +185,7 @@ exports.up = function (knex/*, Promise*/) {
table.string('object_type').notNull().defaultTo('');
table.integer('object_id').notNull().unsigned().defaultTo(0);
table.string('action').notNull();
table.json('meta').notNull().defaultTo('{}');
table.json('meta').notNull();
});
})
.then(() => {

View File

@ -14,6 +14,11 @@ class AccessList extends Model {
$beforeInsert () {
this.created_on = Model.raw('NOW()');
this.modified_on = Model.raw('NOW()');
// Default for meta
if (typeof this.meta === 'undefined') {
this.meta = {};
}
}
$beforeUpdate () {

View File

@ -12,6 +12,11 @@ class AccessListAuth extends Model {
$beforeInsert () {
this.created_on = Model.raw('NOW()');
this.modified_on = Model.raw('NOW()');
// Default for meta
if (typeof this.meta === 'undefined') {
this.meta = {};
}
}
$beforeUpdate () {

View File

@ -13,6 +13,11 @@ class AuditLog extends Model {
$beforeInsert () {
this.created_on = Model.raw('NOW()');
this.modified_on = Model.raw('NOW()');
// Default for meta
if (typeof this.meta === 'undefined') {
this.meta = {};
}
}
$beforeUpdate () {

View File

@ -29,6 +29,11 @@ class Auth extends Model {
this.created_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);
}

View File

@ -14,13 +14,31 @@ class Certificate extends Model {
this.created_on = Model.raw('NOW()');
this.modified_on = Model.raw('NOW()');
// Default for expires_on
if (typeof this.expires_on === 'undefined') {
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 () {
this.modified_on = Model.raw('NOW()');
// Sort domain_names
if (typeof this.domain_names !== 'undefined') {
this.domain_names.sort();
}
}
static get name () {

View File

@ -14,10 +14,27 @@ class DeadHost extends Model {
$beforeInsert () {
this.created_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 () {
this.modified_on = Model.raw('NOW()');
// Sort domain_names
if (typeof this.domain_names !== 'undefined') {
this.domain_names.sort();
}
}
static get name () {

View File

@ -15,11 +15,24 @@ class ProxyHost extends Model {
$beforeInsert () {
this.created_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 () {
this.modified_on = Model.raw('NOW()');
// Sort domain_names
if (typeof this.domain_names !== 'undefined') {
this.domain_names.sort();
}

View File

@ -14,10 +14,27 @@ class RedirectionHost extends Model {
$beforeInsert () {
this.created_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 () {
this.modified_on = Model.raw('NOW()');
// Sort domain_names
if (typeof this.domain_names !== 'undefined') {
this.domain_names.sort();
}
}
static get name () {

View File

@ -13,6 +13,11 @@ class Stream extends Model {
$beforeInsert () {
this.created_on = Model.raw('NOW()');
this.modified_on = Model.raw('NOW()');
// Default for meta
if (typeof this.meta === 'undefined') {
this.meta = {};
}
}
$beforeUpdate () {

View File

@ -19,7 +19,6 @@ module.exports = function () {
let token_data = {};
let self = {
//return {
/**
* @param {Object} payload
* @param {Object} [user_options]

View File

@ -13,6 +13,11 @@ class User extends Model {
$beforeInsert () {
this.created_on = Model.raw('NOW()');
this.modified_on = Model.raw('NOW()');
// Default for roles
if (typeof this.roles === 'undefined') {
this.roles = [];
}
}
$beforeUpdate () {

View File

@ -16,9 +16,9 @@ server {
{% include "_forced_ssl.conf" %}
{% 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;
{% else %}
return 301 $scheme://{{ forward_domain_name }};
{% endif %}
}
}