v2.1.0 (#293)
* Fix wrapping when too many hosts are shown (#207) * Update npm packages, fixes CVE-2019-10757 * Revert some breaking packages * Major overhaul - Docker buildx support in CI - Cypress API Testing in CI - Restructured folder layout (insert clean face meme) - Added Swagger documentation and validate API against that (to be completed) - Use common base image for all supported archs, which includes updated nginx with ipv6 support - Updated certbot and changes required for it - Large amount of Hosts names will wrap in UI - Updated packages for frontend - Version bump 2.1.0 * Updated documentation * Fix JWT expire time going crazy. Now set to 1day * Backend JS formatting rules * Remove v1 importer, I doubt anyone is using v1 anymore * Added backend formatting rules and enforce them in Jenkins builds * Fix CI, doesn't need a tty * Thanks bcrypt. Why can't you just be normal. * Cleanup after syntax check Co-authored-by: Marcelo Castagna <margaale@users.noreply.github.com>
This commit is contained in:
.babelrc.gitignore
.jenkins
.versionDockerfileDockerfile.arm64Dockerfile.armv6lDockerfile.armv7lJenkinsfileREADME.mdbackend
.eslintrc.json.gitignore.prettierrcapp.js
config
db.jsdoc
index.jsinternal
access-list.jsaudit-log.jscertificate.jsdead-host.jshost.jsip_ranges.jsnginx.jsproxy-host.jsredirection-host.jsreport.jssetting.jsstream.jstoken.jsuser.js
knexfile.jslib
access.js
logger.jsmigrate.jsaccess
access_lists-create.jsonaccess_lists-delete.jsonaccess_lists-get.jsonaccess_lists-list.jsonaccess_lists-update.jsonauditlog-list.jsoncertificates-create.jsoncertificates-delete.jsoncertificates-get.jsoncertificates-list.jsoncertificates-update.jsondead_hosts-create.jsondead_hosts-delete.jsondead_hosts-get.jsondead_hosts-list.jsondead_hosts-update.jsonpermissions.jsonproxy_hosts-create.jsonproxy_hosts-delete.jsonproxy_hosts-get.jsonproxy_hosts-list.jsonproxy_hosts-update.jsonredirection_hosts-create.jsonredirection_hosts-delete.jsonredirection_hosts-get.jsonredirection_hosts-list.jsonredirection_hosts-update.jsonreports-hosts.jsonroles.jsonsettings-get.jsonsettings-list.jsonsettings-update.jsonstreams-create.jsonstreams-delete.jsonstreams-get.jsonstreams-list.jsonstreams-update.jsonusers-create.jsonusers-delete.jsonusers-get.jsonusers-list.jsonusers-loginas.jsonusers-password.jsonusers-permissions.jsonusers-update.json
error.jsexpress
helpers.jsmigrate_template.jsutils.jsvalidator
migrations
20180618015850_initial.js20180929054513_websockets.js20181019052346_forward_host.js20181113041458_http2_support.js20181213013211_forward_scheme.js20190104035154_disabled.js20190215115310_customlocations.js20190218060101_hsts.js20190227065017_settings.js
models
access_list.jsaccess_list_auth.jsaudit-log.jsauth.jscertificate.jsdead_host.jsproxy_host.jsredirection_host.jssetting.jsstream.jstoken.jsuser.jsuser_permission.js
nodemon.jsonpackage.jsonroutes
api
schema
definitions.json
setup.jsendpoints
access-lists.jsoncertificates.jsondead-hosts.jsonproxy-hosts.jsonredirection-hosts.jsonsettings.jsonstreams.jsontokens.jsonusers.json
examples.jsonindex.jsontemplates
_assets.conf_certificates.conf_exploits.conf_forced_ssl.conf_header_comment.conf_hsts.conf_listen.conf_location.confdead_host.confdefault.confip_ranges.confletsencrypt-request.confproxy_host.confredirection_host.confstream.conf
yarn.lockbin
config
doc
docker-compose.ymldocker
Dockerfile
dev
docker-compose.ci.ymldocker-compose.dev.ymlrootfs
bin
etc
cont-finish.d
cont-init.d
fix-attrs.d
letsencrypt.ininginx
conf.d
default.confdev.conf
mime.typesnginx.confinclude
.gitignoreassets.confblock-exploits.confforce-ssl.confip_ranges.confletsencrypt-acme-challenge.confproxy.confssl-ciphers.conf
production.confservices.d
root
var
www
html
frontend
.babelrc.gitignorepackage.json
knexfile.jspackage.jsonapp-images
default-avatar.jpg
fontsfavicons
html
imagesjs
app
api.jsrouter.js
audit-log
cache.jscontroller.jsdashboard
empty
error
help
i18n.jsmain.jsnginx
access
certificates-list-item.ejscertificates
dead
proxy
access-list-item.ejsdelete.ejsdelete.jsform.ejsform.js
list
location-item.ejslocation.jsmain.ejsmain.jsredirection
stream
settings
tokens.jsui
user
users
i18n
index.jslib
login.jslogin
models
scss
webpack.config.jsyarn.lockrootfs
scripts
src
backend
app.jsdb.jsimporter.jsindex.js
internal
access-list.jsaudit-log.jscertificate.jsdead-host.jshost.jsip_ranges.jsnginx.jsproxy-host.jsredirection-host.jsreport.jssetting.jsstream.jstoken.jsuser.js
lib
access.js
logger.jsmigrate.jsaccess
access_lists-create.jsonaccess_lists-delete.jsonaccess_lists-get.jsonaccess_lists-list.jsonaccess_lists-update.jsonauditlog-list.jsoncertificates-create.jsoncertificates-delete.jsoncertificates-get.jsoncertificates-list.jsoncertificates-update.jsondead_hosts-create.jsondead_hosts-delete.jsondead_hosts-get.jsondead_hosts-list.jsondead_hosts-update.jsonpermissions.jsonproxy_hosts-create.jsonproxy_hosts-delete.jsonproxy_hosts-get.jsonproxy_hosts-list.jsonproxy_hosts-update.jsonredirection_hosts-create.jsonredirection_hosts-delete.jsonredirection_hosts-get.jsonredirection_hosts-list.jsonredirection_hosts-update.jsonreports-hosts.jsonroles.jsonsettings-get.jsonsettings-list.jsonsettings-update.jsonstreams-create.jsonstreams-delete.jsonstreams-get.jsonstreams-list.jsonstreams-update.jsonusers-create.jsonusers-delete.jsonusers-get.jsonusers-list.jsonusers-loginas.jsonusers-password.jsonusers-permissions.jsonusers-update.json
error.jsexpress
helpers.jsmigrate_template.jsutils.jsvalidator
migrations
20180618015850_initial.js20180929054513_websockets.js20181113041458_http2_support.js20190104035154_disabled.js20190218060101_hsts.js20190227065017_settings.js
models
access_list.jsaccess_list_auth.jsaudit-log.jsauth.jscertificate.jsdead_host.jsproxy_host.jsredirection_host.jssetting.jsstream.jstoken.jsuser.jsuser_permission.js
routes
setup.jsviews
partials
frontend
test
.eslintrc.json.gitignore.prettierrcREADME.md
webpack.config.jscypress
jsconfig.jsonpackage.jsonyarn.lock
142
test/cypress/plugins/backendApi/client.js
Normal file
142
test/cypress/plugins/backendApi/client.js
Normal file
@ -0,0 +1,142 @@
|
||||
const logger = require('./logger');
|
||||
const restler = require('@jc21/restler');
|
||||
|
||||
const BackendApi = function(config, token) {
|
||||
this.config = config;
|
||||
this.token = token;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} token
|
||||
*/
|
||||
BackendApi.prototype.setToken = function(token) {
|
||||
this.token = token;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @param {bool} [returnOnError]
|
||||
* @returns {Promise<object>}
|
||||
*/
|
||||
BackendApi.prototype.get = function(path, returnOnError) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let headers = {
|
||||
Accept: 'application/json'
|
||||
};
|
||||
if (this.token) {
|
||||
headers.Authorization = 'Bearer ' + this.token;
|
||||
}
|
||||
|
||||
logger('GET ', this.config.baseUrl + path);
|
||||
|
||||
restler
|
||||
.get(this.config.baseUrl + path, {
|
||||
headers: headers,
|
||||
})
|
||||
.on('complete', function(data, response) {
|
||||
logger('Response data:', data);
|
||||
if (!returnOnError && data instanceof Error) {
|
||||
reject(data);
|
||||
} else if (!returnOnError && response.statusCode != 200) {
|
||||
if (typeof data === 'object' && typeof data.error === 'object' && typeof data.error.message !== 'undefined') {
|
||||
reject(new Error(data.error.code + ': ' + data.error.message));
|
||||
} else {
|
||||
reject(new Error('Error ' + response.statusCode));
|
||||
}
|
||||
} else {
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @param {bool} [returnOnError]
|
||||
* @returns {Promise<object>}
|
||||
*/
|
||||
BackendApi.prototype.delete = function(path, returnOnError) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let headers = {
|
||||
Accept: 'application/json'
|
||||
};
|
||||
if (this.token) {
|
||||
headers.Authorization = 'Bearer ' + this.token;
|
||||
}
|
||||
|
||||
logger('DELETE ', this.config.baseUrl + path);
|
||||
|
||||
restler
|
||||
.del(this.config.baseUrl + path, {
|
||||
headers: headers,
|
||||
})
|
||||
.on('complete', function(data, response) {
|
||||
logger('Response data:', data);
|
||||
if (!returnOnError && data instanceof Error) {
|
||||
reject(data);
|
||||
} else if (!returnOnError && response.statusCode != 200) {
|
||||
if (typeof data === 'object' && typeof data.error === 'object' && typeof data.error.message !== 'undefined') {
|
||||
reject(new Error(data.error.code + ': ' + data.error.message));
|
||||
} else {
|
||||
reject(new Error('Error ' + response.statusCode));
|
||||
}
|
||||
} else {
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @param {object} data
|
||||
* @param {bool} [returnOnError]
|
||||
* @returns {Promise<object>}
|
||||
*/
|
||||
BackendApi.prototype.postJson = function(path, data, returnOnError) {
|
||||
logger('POST ', this.config.baseUrl + path);
|
||||
return this._putPostJson('postJson', path, data, returnOnError);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @param {object} data
|
||||
* @param {bool} [returnOnError]
|
||||
* @returns {Promise<object>}
|
||||
*/
|
||||
BackendApi.prototype.putJson = function(path, data, returnOnError) {
|
||||
logger('PUT ', this.config.baseUrl + path);
|
||||
return this._putPostJson('putJson', path, data, returnOnError);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @param {object} data
|
||||
* @param {bool} [returnOnError]
|
||||
* @returns {Promise<object>}
|
||||
*/
|
||||
BackendApi.prototype._putPostJson = function(fn, path, data, returnOnError) {
|
||||
return new Promise((resolve, reject) => {
|
||||
restler[fn](this.config.baseUrl + path, data, {
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: 'Bearer ' + this.token,
|
||||
},
|
||||
}).on('complete', function(data, response) {
|
||||
logger('Response data:', data);
|
||||
if (!returnOnError && data instanceof Error) {
|
||||
reject(data);
|
||||
} else if (!returnOnError && response.statusCode != 200) {
|
||||
if (typeof data === 'object' && typeof data.error === 'object' && typeof data.error.message !== 'undefined') {
|
||||
reject(new Error(data.error.code + ': ' + data.error.message));
|
||||
} else {
|
||||
reject(new Error('Error ' + response.statusCode));
|
||||
}
|
||||
} else {
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = BackendApi;
|
8
test/cypress/plugins/backendApi/logger.js
Normal file
8
test/cypress/plugins/backendApi/logger.js
Normal file
@ -0,0 +1,8 @@
|
||||
const _ = require('lodash');
|
||||
const chalk = require('chalk');
|
||||
|
||||
module.exports = function () {
|
||||
var arr = _.values(arguments);
|
||||
arr.unshift(chalk.blue.bold('[') + chalk.yellow.bold('Backend API') + chalk.blue.bold(']'));
|
||||
console.log.apply(null, arr);
|
||||
};
|
64
test/cypress/plugins/backendApi/task.js
Normal file
64
test/cypress/plugins/backendApi/task.js
Normal file
@ -0,0 +1,64 @@
|
||||
const logger = require('./logger');
|
||||
const Client = require('./client');
|
||||
|
||||
module.exports = function (config) {
|
||||
|
||||
logger('Client Ready using', config.baseUrl);
|
||||
|
||||
return {
|
||||
|
||||
/**
|
||||
* @param {object} options
|
||||
* @param {string} options.path API path
|
||||
* @param {string} [options.token] JWT
|
||||
* @param {bool} [options.returnOnError] If true, will return instead of throwing errors
|
||||
* @returns {string}
|
||||
*/
|
||||
backendApiGet: (options) => {
|
||||
const api = new Client(config);
|
||||
api.setToken(options.token);
|
||||
return api.get(options.path, options.returnOnError || false);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {object} options
|
||||
* @param {string} options.token JWT
|
||||
* @param {string} options.path API path
|
||||
* @param {object} options.data
|
||||
* @param {bool} [options.returnOnError] If true, will return instead of throwing errors
|
||||
* @returns {string}
|
||||
*/
|
||||
backendApiPost: (options) => {
|
||||
const api = new Client(config);
|
||||
api.setToken(options.token);
|
||||
return api.postJson(options.path, options.data, options.returnOnError || false);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {object} options
|
||||
* @param {string} options.token JWT
|
||||
* @param {string} options.path API path
|
||||
* @param {object} options.data
|
||||
* @param {bool} [options.returnOnError] If true, will return instead of throwing errors
|
||||
* @returns {string}
|
||||
*/
|
||||
backendApiPut: (options) => {
|
||||
const api = new Client(config);
|
||||
api.setToken(options.token);
|
||||
return api.putJson(options.path, options.data, options.returnOnError || false);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {object} options
|
||||
* @param {string} options.token JWT
|
||||
* @param {string} options.path API path
|
||||
* @param {bool} [options.returnOnError] If true, will return instead of throwing errors
|
||||
* @returns {string}
|
||||
*/
|
||||
backendApiDelete: (options) => {
|
||||
const api = new Client(config);
|
||||
api.setToken(options.token);
|
||||
return api.delete(options.path, options.returnOnError || false);
|
||||
}
|
||||
};
|
||||
};
|
20
test/cypress/plugins/index.js
Normal file
20
test/cypress/plugins/index.js
Normal file
@ -0,0 +1,20 @@
|
||||
const {SwaggerValidation} = require('@jc21/cypress-swagger-validation');
|
||||
|
||||
module.exports = (on, config) => {
|
||||
// Replace swaggerBase config var wildcard
|
||||
if (typeof config.env.swaggerBase !== 'undefined') {
|
||||
config.env.swaggerBase = config.env.swaggerBase.replace('{{baseUrl}}', config.baseUrl);
|
||||
}
|
||||
|
||||
// Plugin Events
|
||||
on('task', SwaggerValidation(config));
|
||||
on('task', require('./backendApi/task')(config));
|
||||
on('task', {
|
||||
log(message) {
|
||||
console.log(message);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
return config;
|
||||
};
|
Reference in New Issue
Block a user