update nginx/dep updates/fix eslint/change line endings

Signed-off-by: Zoey <zoey@z0ey.de>
This commit is contained in:
Zoey
2024-03-25 18:24:21 +01:00
parent ef5ac4cbd8
commit 906d7ce04a
96 changed files with 2579 additions and 2859 deletions

View File

@@ -8,24 +8,24 @@
*
*/
const _ = require('lodash');
const logger = require('../logger').access;
const validator = require('ajv');
const error = require('./error');
const userModel = require('../models/user');
const _ = require('lodash');
const logger = require('../logger').access;
const validator = require('ajv');
const error = require('./error');
const userModel = require('../models/user');
const proxyHostModel = require('../models/proxy_host');
const TokenModel = require('../models/token');
const roleSchema = require('./access/roles.json');
const permsSchema = require('./access/permissions.json');
const TokenModel = require('../models/token');
const roleSchema = require('./access/roles.json');
const permsSchema = require('./access/permissions.json');
module.exports = function (token_string) {
let Token = new TokenModel();
let token_data = null;
let initialized = false;
let object_cache = {};
const Token = new TokenModel();
let token_data = null;
let initialized = false;
const object_cache = {};
let allow_internal_access = false;
let user_roles = [];
let permissions = {};
let user_roles = [];
let permissions = {};
/**
* Loads the Token object from the token string
@@ -39,8 +39,8 @@ module.exports = function (token_string) {
} else if (!token_string) {
reject(new error.PermissionError('Permission Denied'));
} else {
resolve(Token.load(token_string)
.then((data) => {
resolve(
Token.load(token_string).then((data) => {
token_data = data;
// At this point we need to load the user from the DB and make sure they:
@@ -75,10 +75,9 @@ module.exports = function (token_string) {
throw new error.AuthError('Invalid token scope for User');
} else {
initialized = true;
user_roles = user.roles;
user_roles = user.roles;
permissions = user.permissions;
}
} else {
throw new error.AuthError('User cannot be loaded for Token');
}
@@ -86,7 +85,8 @@ module.exports = function (token_string) {
} else {
initialized = true;
}
}));
}),
);
}
});
};
@@ -105,49 +105,45 @@ module.exports = function (token_string) {
if (typeof token_data.attrs.id === 'undefined' || !token_data.attrs.id) {
reject(new error.AuthError('User Token supplied without a User ID'));
} else {
let token_user_id = token_data.attrs.id ? token_data.attrs.id : 0;
const token_user_id = token_data.attrs.id ? token_data.attrs.id : 0;
let query;
if (typeof object_cache[object_type] === 'undefined') {
switch (object_type) {
// USERS - should only return yourself
case 'users':
resolve(token_user_id ? [token_user_id] : []);
break;
// USERS - should only return yourself
case 'users':
resolve(token_user_id ? [token_user_id] : []);
break;
// Proxy Hosts
case 'proxy_hosts':
query = proxyHostModel
.query()
.select('id')
.andWhere('is_deleted', 0);
case 'proxy_hosts':
query = proxyHostModel.query().select('id').andWhere('is_deleted', 0);
if (permissions.visibility === 'user') {
query.andWhere('owner_user_id', token_user_id);
}
if (permissions.visibility === 'user') {
query.andWhere('owner_user_id', token_user_id);
}
resolve(query
.then((rows) => {
let result = [];
_.forEach(rows, (rule_row) => {
result.push(rule_row.id);
});
resolve(
query.then((rows) => {
const result = [];
_.forEach(rows, (rule_row) => {
result.push(rule_row.id);
});
// enum should not have less than 1 item
if (!result.length) {
result.push(0);
}
// enum should not have less than 1 item
if (!result.length) {
result.push(0);
}
return result;
})
);
break;
return result;
}),
);
break;
// DEFAULT: null
default:
resolve(null);
break;
default:
resolve(null);
break;
}
} else {
resolve(object_cache[object_type]);
@@ -156,11 +152,10 @@ module.exports = function (token_string) {
} else {
resolve(null);
}
})
.then((objects) => {
object_cache[object_type] = objects;
return objects;
});
}).then((objects) => {
object_cache[object_type] = objects;
return objects;
});
};
/**
@@ -170,51 +165,49 @@ module.exports = function (token_string) {
* @returns {Object}
*/
this.getObjectSchema = (permission_label) => {
let base_object_type = permission_label.split(':').shift();
const base_object_type = permission_label.split(':').shift();
let schema = {
$id: 'objects',
$schema: 'http://json-schema.org/draft-07/schema#',
description: 'Actor Properties',
type: 'object',
const schema = {
$id: 'objects',
$schema: 'http://json-schema.org/draft-07/schema#',
description: 'Actor Properties',
type: 'object',
additionalProperties: false,
properties: {
properties: {
user_id: {
anyOf: [
{
type: 'number',
enum: [Token.get('attrs').id]
}
]
enum: [Token.get('attrs').id],
},
],
},
scope: {
type: 'string',
pattern: '^' + Token.get('scope') + '$'
}
}
type: 'string',
pattern: '^' + Token.get('scope') + '$',
},
},
};
return this.loadObjects(base_object_type)
.then((object_result) => {
if (typeof object_result === 'object' && object_result !== null) {
schema.properties[base_object_type] = {
type: 'number',
enum: object_result,
minimum: 1
};
} else {
schema.properties[base_object_type] = {
type: 'number',
minimum: 1
};
}
return this.loadObjects(base_object_type).then((object_result) => {
if (typeof object_result === 'object' && object_result !== null) {
schema.properties[base_object_type] = {
type: 'number',
enum: object_result,
minimum: 1,
};
} else {
schema.properties[base_object_type] = {
type: 'number',
minimum: 1,
};
}
return schema;
});
return schema;
});
};
return {
token: Token,
/**
@@ -223,7 +216,7 @@ module.exports = function (token_string) {
* @returns {Promise}
*/
load: (allow_internal) => {
return new Promise(function (resolve/*, reject*/) {
return new Promise(function (resolve /*, reject */) {
if (token_string) {
resolve(Token.load(token_string));
} else {
@@ -244,71 +237,64 @@ module.exports = function (token_string) {
can: (permission, data) => {
if (allow_internal_access === true) {
return Promise.resolve(true);
//return true;
// return true;
} else {
return this.init()
.then(() => {
// initialized, token decoded ok
return this.getObjectSchema(permission)
.then((objectSchema) => {
let data_schema = {
[permission]: {
data: data,
scope: Token.get('scope'),
roles: user_roles,
permission_visibility: permissions.visibility,
permission_proxy_hosts: permissions.proxy_hosts,
permission_redirection_hosts: permissions.redirection_hosts,
permission_dead_hosts: permissions.dead_hosts,
permission_streams: permissions.streams,
permission_access_lists: permissions.access_lists,
permission_certificates: permissions.certificates
}
};
return this.getObjectSchema(permission).then((objectSchema) => {
const data_schema = {
[permission]: {
data,
scope: Token.get('scope'),
roles: user_roles,
permission_visibility: permissions.visibility,
permission_proxy_hosts: permissions.proxy_hosts,
permission_redirection_hosts: permissions.redirection_hosts,
permission_dead_hosts: permissions.dead_hosts,
permission_streams: permissions.streams,
permission_access_lists: permissions.access_lists,
permission_certificates: permissions.certificates,
},
};
let permissionSchema = {
$schema: 'http://json-schema.org/draft-07/schema#',
$async: true,
$id: 'permissions',
additionalProperties: false,
properties: {}
};
const permissionSchema = {
$schema: 'http://json-schema.org/draft-07/schema#',
$async: true,
$id: 'permissions',
additionalProperties: false,
properties: {},
};
permissionSchema.properties[permission] = require('./access/' + permission.replace(/:/gim, '-') + '.json');
permissionSchema.properties[permission] = require('./access/' + permission.replace(/:/gim, '-') + '.json');
// logger.info('objectSchema', JSON.stringify(objectSchema, null, 2));
// logger.info('permissionSchema', JSON.stringify(permissionSchema, null, 2));
// logger.info('data_schema', JSON.stringify(data_schema, null, 2));
// logger.info('objectSchema', JSON.stringify(objectSchema, null, 2));
// logger.info('permissionSchema', JSON.stringify(permissionSchema, null, 2));
// logger.info('data_schema', JSON.stringify(data_schema, null, 2));
let ajv = validator({
verbose: true,
allErrors: true,
format: 'full',
missingRefs: 'fail',
breakOnError: true,
coerceTypes: true,
schemas: [
roleSchema,
permsSchema,
objectSchema,
permissionSchema
]
});
return ajv.validate('permissions', data_schema)
.then(() => {
return data_schema[permission];
});
const ajv = validator({
verbose: true,
allErrors: true,
format: 'full',
missingRefs: 'fail',
breakOnError: true,
coerceTypes: true,
schemas: [roleSchema, permsSchema, objectSchema, permissionSchema],
});
return ajv.validate('permissions', data_schema).then(() => {
return data_schema[permission];
});
});
})
.catch((err) => {
err.permission = permission;
err.permission = permission;
err.permission_data = data;
logger.error(permission, data, err.message);
throw new error.PermissionError('Permission Denied', err);
});
}
}
},
};
};

View File

@@ -1,11 +1,10 @@
const dnsPlugins = require('../certbot-dns-plugins.json');
const utils = require('./utils');
const error = require('./error');
const logger = require('../logger').certbot;
const batchflow = require('batchflow');
const utils = require('./utils');
const error = require('./error');
const logger = require('../logger').certbot;
const batchflow = require('batchflow');
const certbot = {
/**
* @param {array} pluginKeys
*/
@@ -18,9 +17,11 @@ const certbot = {
return;
}
batchflow(pluginKeys).sequential()
batchflow(pluginKeys)
.sequential()
.each((i, pluginKey, next) => {
certbot.installPlugin(pluginKey)
certbot
.installPlugin(pluginKey)
.then(() => {
next();
})
@@ -59,7 +60,8 @@ const certbot = {
logger.start(`Installing ${pluginKey}...`);
const cmd = 'pip install --no-cache-dir ' + plugin.package_name;
return utils.exec(cmd)
return utils
.exec(cmd)
.then((result) => {
logger.complete(`Installed ${pluginKey}`);
return result;

View File

@@ -1,6 +1,6 @@
const fs = require('fs');
const fs = require('fs');
const NodeRSA = require('node-rsa');
const logger = require('../logger').global;
const logger = require('../logger').global;
const keysFile = '/data/etc/npm/keys.json';
@@ -14,13 +14,13 @@ const configure = () => {
let configData;
try {
configData = require(filename);
} catch (err) {
} catch {
// do nothing
}
if (configData && configData.database) {
logger.info(`Using configuration from file: ${filename}`);
instance = configData;
instance = configData;
instance.keys = getKeys();
return;
}
@@ -29,20 +29,20 @@ const configure = () => {
const envMysqlHost = process.env.DB_MYSQL_HOST || null;
const envMysqlUser = process.env.DB_MYSQL_USER || null;
const envMysqlName = process.env.DB_MYSQL_NAME || null;
const envMysqlTls = process.env.DB_MYSQL_TLS || null;
const envMysqlCa = process.env.DB_MYSQL_CA || '/etc/ssl/certs/ca-certificates.crt';
const envMysqlTls = process.env.DB_MYSQL_TLS || null;
const envMysqlCa = process.env.DB_MYSQL_CA || '/etc/ssl/certs/ca-certificates.crt';
if (envMysqlHost && envMysqlUser && envMysqlName) {
// we have enough mysql creds to go with mysql
logger.info('Using MySQL configuration');
instance = {
database: {
engine: 'mysql',
host: envMysqlHost,
port: process.env.DB_MYSQL_PORT || 3306,
user: envMysqlUser,
engine: 'mysql',
host: envMysqlHost,
port: process.env.DB_MYSQL_PORT || 3306,
user: envMysqlUser,
password: process.env.DB_MYSQL_PASSWORD,
name: envMysqlName,
ssl: envMysqlTls ? { ca: fs.readFileSync(envMysqlCa) } : false,
name: envMysqlName,
ssl: envMysqlTls ? { ca: fs.readFileSync(envMysqlCa) } : false,
},
keys: getKeys(),
};
@@ -54,13 +54,13 @@ const configure = () => {
instance = {
database: {
engine: 'knex-native',
knex: {
client: 'sqlite3',
knex: {
client: 'sqlite3',
connection: {
filename: envSqliteFile
filename: envSqliteFile,
},
useNullAsDefault: true
}
useNullAsDefault: true,
},
},
keys: getKeys(),
};
@@ -103,18 +103,17 @@ const generateKeys = () => {
};
module.exports = {
/**
*
* @param {string} key ie: 'database' or 'database.engine'
* @returns {boolean}
*/
has: function(key) {
has: function (key) {
instance === null && configure();
const keys = key.split('.');
let level = instance;
let has = true;
keys.forEach((keyItem) =>{
let level = instance;
let has = true;
keys.forEach((keyItem) => {
if (typeof level[keyItem] === 'undefined') {
has = false;
} else {
@@ -183,5 +182,5 @@ module.exports = {
*/
useLetsencryptStaging: function () {
return !!process.env.LE_STAGING;
}
},
};

View File

@@ -1,96 +1,95 @@
const _ = require('lodash');
const _ = require('lodash');
const util = require('util');
module.exports = {
PermissionError: function (message, previous) {
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.name = this.constructor.name;
this.previous = previous;
this.message = 'Permission Denied';
this.public = true;
this.status = 403;
this.message = 'Permission Denied';
this.public = true;
this.status = 403;
},
ItemNotFoundError: function (id, previous) {
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.name = this.constructor.name;
this.previous = previous;
this.message = 'Item Not Found - ' + id;
this.public = true;
this.status = 404;
this.message = 'Item Not Found - ' + id;
this.public = true;
this.status = 404;
},
AuthError: function (message, previous) {
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.name = this.constructor.name;
this.previous = previous;
this.message = message;
this.public = true;
this.status = 401;
this.message = message;
this.public = true;
this.status = 401;
},
InternalError: function (message, previous) {
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.name = this.constructor.name;
this.previous = previous;
this.message = message;
this.status = 500;
this.public = false;
this.message = message;
this.status = 500;
this.public = false;
},
InternalValidationError: function (message, previous) {
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.name = this.constructor.name;
this.previous = previous;
this.message = message;
this.status = 400;
this.public = false;
this.message = message;
this.status = 400;
this.public = false;
},
ConfigurationError: function (message, previous) {
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.name = this.constructor.name;
this.previous = previous;
this.message = message;
this.status = 400;
this.public = true;
this.message = message;
this.status = 400;
this.public = true;
},
CacheError: function (message, previous) {
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.message = message;
this.name = this.constructor.name;
this.message = message;
this.previous = previous;
this.status = 500;
this.public = false;
this.status = 500;
this.public = false;
},
ValidationError: function (message, previous) {
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.name = this.constructor.name;
this.previous = previous;
this.message = message;
this.public = true;
this.status = 400;
this.message = message;
this.public = true;
this.status = 400;
},
AssertionFailedError: function (message, previous) {
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.name = this.constructor.name;
this.previous = previous;
this.message = message;
this.public = false;
this.status = 400;
this.message = message;
this.public = false;
this.status = 400;
},
CommandError: function (stdErr, code, previous) {
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.name = this.constructor.name;
this.previous = previous;
this.message = stdErr;
this.code = code;
this.public = false;
this.message = stdErr;
this.code = code;
this.public = false;
},
};

View File

@@ -1,40 +1,36 @@
const validator = require('../validator');
module.exports = function (req, res, next) {
if (req.headers.origin) {
const originSchema = {
oneOf: [
{
type: 'string',
pattern: '^[a-z\\-]+:\\/\\/(?:[\\w\\-\\.]+(:[0-9]+)?/?)?$'
type: 'string',
pattern: '^[a-z\\-]+:\\/\\/(?:[\\w\\-\\.]+(:[0-9]+)?/?)?$',
},
{
type: 'string',
pattern: '^[a-z\\-]+:\\/\\/(?:\\[([a-z0-9]{0,4}\\:?)+\\])?/?(:[0-9]+)?$'
}
]
type: 'string',
pattern: '^[a-z\\-]+:\\/\\/(?:\\[([a-z0-9]{0,4}\\:?)+\\])?/?(:[0-9]+)?$',
},
],
};
// very relaxed validation....
validator(originSchema, req.headers.origin)
.then(function () {
res.set({
'Access-Control-Allow-Origin': req.headers.origin,
'Access-Control-Allow-Origin': req.headers.origin,
'Access-Control-Allow-Credentials': true,
'Access-Control-Allow-Methods': 'OPTIONS, GET, POST',
'Access-Control-Allow-Headers': 'Content-Type, Cache-Control, Pragma, Expires, Authorization, X-Dataset-Total, X-Dataset-Offset, X-Dataset-Limit',
'Access-Control-Max-Age': 5 * 60,
'Access-Control-Expose-Headers': 'X-Dataset-Total, X-Dataset-Offset, X-Dataset-Limit'
'Access-Control-Allow-Methods': 'OPTIONS, GET, POST',
'Access-Control-Allow-Headers': 'Content-Type, Cache-Control, Pragma, Expires, Authorization, X-Dataset-Total, X-Dataset-Offset, X-Dataset-Limit',
'Access-Control-Max-Age': 5 * 60,
'Access-Control-Expose-Headers': 'X-Dataset-Total, X-Dataset-Offset, X-Dataset-Limit',
});
next();
})
.catch(next);
} else {
// No origin
next();
}
};

View File

@@ -3,8 +3,9 @@ const Access = require('../access');
module.exports = () => {
return function (req, res, next) {
res.locals.access = null;
let access = new Access(res.locals.token || null);
access.load()
const access = new Access(res.locals.token || null);
access
.load()
.then(() => {
res.locals.access = access;
next();
@@ -12,4 +13,3 @@ module.exports = () => {
.catch(next);
};
};

View File

@@ -1,7 +1,7 @@
module.exports = function () {
return function (req, res, next) {
if (req.headers.authorization) {
let parts = req.headers.authorization.split(' ');
const parts = req.headers.authorization.split(' ');
if (parts && parts[0] === 'Bearer' && parts[1]) {
res.locals.token = parts[1];

View File

@@ -1,7 +1,6 @@
let _ = require('lodash');
const _ = require('lodash');
module.exports = function (default_sort, default_offset, default_limit, max_limit) {
/**
* This will setup the req query params with filtered data and defaults
*
@@ -12,33 +11,32 @@ module.exports = function (default_sort, default_offset, default_limit, max_limi
*/
return function (req, res, next) {
req.query.offset = typeof req.query.limit === 'undefined' ? default_offset || 0 : parseInt(req.query.offset, 10);
req.query.limit = typeof req.query.limit === 'undefined' ? default_limit || 50 : parseInt(req.query.limit, 10);
req.query.limit = typeof req.query.limit === 'undefined' ? default_limit || 50 : parseInt(req.query.limit, 10);
if (max_limit && req.query.limit > max_limit) {
req.query.limit = max_limit;
}
// Sorting
let sort = typeof req.query.sort === 'undefined' ? default_sort : req.query.sort;
let myRegexp = /.*\.(asc|desc)$/ig;
let sort_array = [];
let sort = typeof req.query.sort === 'undefined' ? default_sort : req.query.sort;
const myRegexp = /.*\.(asc|desc)$/gi;
const sort_array = [];
sort = sort.split(',');
_.map(sort, function (val) {
let matches = myRegexp.exec(val);
const matches = myRegexp.exec(val);
if (matches !== null) {
let dir = matches[1];
const dir = matches[1];
sort_array.push({
field: val.substr(0, val.length - (dir.length + 1)),
dir: dir.toLowerCase()
dir: dir.toLowerCase(),
});
} else {
sort_array.push({
field: val,
dir: 'asc'
dir: 'asc',
});
}
});

View File

@@ -1,7 +1,6 @@
const moment = require('moment');
module.exports = {
/**
* Takes an expression such as 30d and returns a moment object of that date in future
*
@@ -21,12 +20,11 @@ module.exports = {
* @returns {Object}
*/
parseDatePeriod: function (expression) {
let matches = expression.match(/^([0-9]+)(y|Q|M|w|d|h|m|s|ms)$/m);
const matches = expression.match(/^([0-9]+)(y|Q|M|w|d|h|m|s|ms)$/m);
if (matches) {
return moment().add(matches[1], matches[2]);
}
return null;
}
},
};

View File

@@ -1,5 +1,5 @@
const migrate_name = 'identifier_for_migrate';
const logger = require('../logger').migrate;
const logger = require('../logger').migrate;
/**
* Migrate
@@ -11,12 +11,11 @@ const logger = require('../logger').migrate;
* @returns {Promise}
*/
exports.up = function (knex, Promise) {
logger.info('[' + migrate_name + '] Migrating Up...');
// Create Table example:
/*return knex.schema.createTable('notification', (table) => {
/* return knex.schema.createTable('notification', (table) => {
table.increments().primary();
table.string('name').notNull();
table.string('type').notNull();
@@ -25,7 +24,7 @@ exports.up = function (knex, Promise) {
})
.then(function () {
logger.info('[' + migrate_name + '] Notification Table created');
});*/
}); */
logger.info('[' + migrate_name + '] Migrating Up Complete');
@@ -44,10 +43,10 @@ exports.down = function (knex, Promise) {
// Drop table example:
/*return knex.schema.dropTable('notification')
/* return knex.schema.dropTable('notification')
.then(() => {
logger.info('[' + migrate_name + '] Notification Table dropped');
});*/
}); */
logger.info('[' + migrate_name + '] Migrating Down Complete');

View File

@@ -1,19 +1,17 @@
const _ = require('lodash');
const exec = require('child_process').exec;
const spawn = require('child_process').spawn;
const execFile = require('child_process').execFile;
const _ = require('lodash');
const exec = require('child_process').exec;
const spawn = require('child_process').spawn;
const execFile = require('child_process').execFile;
const { Liquid } = require('liquidjs');
const error = require('./error');
//const logger = require('../logger').global;
const error = require('./error');
// const logger = require('../logger').global;
module.exports = {
/**
* @param {String} cmd
*/
exec: async function(cmd, options = {}) {
//logger.debug('CMD:', cmd);
exec: async function (cmd, options = {}) {
// logger.debug('CMD:', cmd);
const { stdout, stderr } = await new Promise((resolve, reject) => {
const child = exec(cmd, options, (isError, stdout, stderr) => {
@@ -36,7 +34,7 @@ module.exports = {
* @param {Array} args
*/
execFile: async function (cmd, args, options = {}) {
//logger.debug('CMD: ' + cmd + ' ' + (args ? args.join(' ') : ''));
// logger.debug('CMD: ' + cmd + ' ' + (args ? args.join(' ') : ''));
const { stdout, stderr } = await new Promise((resolve, reject) => {
const child = execFile(cmd, args, options, (isError, stdout, stderr) => {
@@ -60,9 +58,9 @@ module.exports = {
execfg: function (cmd) {
return new Promise((resolve, reject) => {
const childProcess = spawn(cmd, {
shell: true,
shell: true,
detached: true,
stdio: 'inherit'
stdio: 'inherit',
});
childProcess.on('error', (err) => {
@@ -119,7 +117,7 @@ module.exports = {
*/
getRenderEngine: function () {
const renderEngine = new Liquid({
root: __dirname + '/../templates/'
root: __dirname + '/../templates/',
});
/**
@@ -136,5 +134,5 @@ module.exports = {
});
return renderEngine;
}
},
};

View File

@@ -1,13 +1,13 @@
const error = require('../error');
const path = require('path');
const error = require('../error');
const path = require('path');
const parser = require('@apidevtools/json-schema-ref-parser');
const ajv = require('ajv')({
verbose: true,
verbose: true,
validateSchema: true,
allErrors: false,
format: 'full',
coerceTypes: true
allErrors: false,
format: 'full',
coerceTypes: true,
});
/**
@@ -15,31 +15,29 @@ const ajv = require('ajv')({
* @param {Object} payload
* @returns {Promise}
*/
function apiValidator (schema, payload/*, description*/) {
return new Promise(function Promise_apiValidator (resolve, reject) {
function apiValidator(schema, payload /*, description */) {
return new Promise(function Promise_apiValidator(resolve, reject) {
if (typeof payload === 'undefined') {
reject(new error.ValidationError('Payload is undefined'));
}
let validate = ajv.compile(schema);
let valid = validate(payload);
const validate = ajv.compile(schema);
const valid = validate(payload);
if (valid && !validate.errors) {
resolve(payload);
} else {
let message = ajv.errorsText(validate.errors);
let err = new error.ValidationError(message);
err.debug = [validate.errors, payload];
const message = ajv.errorsText(validate.errors);
const err = new error.ValidationError(message);
err.debug = [validate.errors, payload];
reject(err);
}
});
}
apiValidator.loadSchemas = parser
.dereference(path.resolve('schema/index.json'))
.then((schema) => {
ajv.addSchema(schema);
return schema;
});
apiValidator.loadSchemas = parser.dereference(path.resolve('schema/index.json')).then((schema) => {
ajv.addSchema(schema);
return schema;
});
module.exports = apiValidator;

View File

@@ -1,17 +1,15 @@
const _ = require('lodash');
const error = require('../error');
const _ = require('lodash');
const error = require('../error');
const definitions = require('../../schema/definitions.json');
RegExp.prototype.toJSON = RegExp.prototype.toString;
const ajv = require('ajv')({
verbose: true,
allErrors: true,
format: 'full', // strict regexes for format checks
verbose: true,
allErrors: true,
format: 'full', // strict regexes for format checks
coerceTypes: true,
schemas: [
definitions
]
schemas: [definitions],
});
/**
@@ -20,30 +18,26 @@ const ajv = require('ajv')({
* @param {Object} payload
* @returns {Promise}
*/
function validator (schema, payload) {
function validator(schema, payload) {
return new Promise(function (resolve, reject) {
if (!payload) {
reject(new error.InternalValidationError('Payload is falsy'));
} else {
try {
let validate = ajv.compile(schema);
const validate = ajv.compile(schema);
let valid = validate(payload);
const valid = validate(payload);
if (valid && !validate.errors) {
resolve(_.cloneDeep(payload));
} else {
let message = ajv.errorsText(validate.errors);
const message = ajv.errorsText(validate.errors);
reject(new error.InternalValidationError(message));
}
} catch (err) {
reject(err);
}
}
});
}
module.exports = validator;