Removing ng-di on the server.

This commit is contained in:
baldo 2018-12-17 22:49:54 +01:00
parent ddb2f47a9d
commit 8697d79ba5
37 changed files with 2838 additions and 2878 deletions

View file

@ -1,12 +1,12 @@
'use strict';
angular.module('ffffng').factory('DatabaseUtil', function (_) {
return {
inCondition: function (field, list) {
return {
query: '(' + field + ' IN (' + _.join(_.times(list.length, _.constant('?')), ', ') + '))',
params: list
};
const _ = require('lodash')
module.exports = {
inCondition (field, list) {
return {
query: '(' + field + ' IN (' + _.join(_.times(list.length, _.constant('?')), ', ') + '))',
params: list
}
};
});
}
}

View file

@ -1,10 +1,8 @@
'use strict';
angular.module('ffffng').factory('ErrorTypes', function () {
return {
badRequest: {code: 400},
notFound: {code: 404},
conflict: {code: 409},
internalError: {code: 500}
};
});
module.exports = {
badRequest: {code: 400},
notFound: {code: 404},
conflict: {code: 409},
internalError: {code: 500}
}

View file

@ -1,224 +1,229 @@
'use strict';
angular.module('ffffng').factory('Resources', function (_, Constraints, Validator, ErrorTypes, Logger) {
function respond(res, httpCode, data, type) {
switch (type) {
case 'html':
res.writeHead(httpCode, {'Content-Type': 'text/html'});
res.end(data);
break;
const _ = require('lodash')
default:
res.writeHead(httpCode, {'Content-Type': 'application/json'});
res.end(JSON.stringify(data));
break;
}
const Constraints = require('../../shared/validation/constraints')
const ErrorTypes = require('../utils/errorTypes')
const Logger = require('../logger')
const Validator = require('../validation/validator')
function respond(res, httpCode, data, type) {
switch (type) {
case 'html':
res.writeHead(httpCode, {'Content-Type': 'text/html'});
res.end(data);
break;
default:
res.writeHead(httpCode, {'Content-Type': 'application/json'});
res.end(JSON.stringify(data));
break;
}
}
function orderByClause(restParams, defaultSortField, allowedSortFields) {
let sortField = _.includes(allowedSortFields, restParams._sortField) ? restParams._sortField : undefined;
if (!sortField) {
sortField = defaultSortField;
}
function orderByClause(restParams, defaultSortField, allowedSortFields) {
var sortField = _.includes(allowedSortFields, restParams._sortField) ? restParams._sortField : undefined;
if (!sortField) {
sortField = defaultSortField;
}
return {
query: 'ORDER BY ' + sortField + ' ' + (restParams._sortDir === 'ASC' ? 'ASC' : 'DESC'),
params: []
};
}
function limitOffsetClause(restParams) {
const page = restParams._page;
const perPage = restParams._perPage;
return {
query: 'LIMIT ? OFFSET ?',
params: [perPage, ((page - 1) * perPage)]
};
}
function escapeForLikePattern(str) {
return str
.replace(/\\/g, '\\\\')
.replace(/%/g, '\\%')
.replace(/_/g, '\\_');
}
function filterCondition(restParams, filterFields) {
if (_.isEmpty(filterFields)) {
return {
query: 'ORDER BY ' + sortField + ' ' + (restParams._sortDir === 'ASC' ? 'ASC' : 'DESC'),
query: '1 = 1',
params: []
};
}
function limitOffsetClause(restParams) {
var page = restParams._page;
var perPage = restParams._perPage;
let query = _.join(
_.map(filterFields, function (field) {
return 'LOWER(' + field + ') LIKE ?';
}),
' OR '
);
return {
query: 'LIMIT ? OFFSET ?',
params: [perPage, ((page - 1) * perPage)]
};
}
query += ' ESCAPE \'\\\'';
function escapeForLikePattern(str) {
return str
.replace(/\\/g, '\\\\')
.replace(/%/g, '\\%')
.replace(/_/g, '\\_');
}
function filterCondition(restParams, filterFields) {
if (_.isEmpty(filterFields)) {
return {
query: '1 = 1',
params: []
};
}
var query = _.join(
_.map(filterFields, function (field) {
return 'LOWER(' + field + ') LIKE ?';
}),
' OR '
);
query += ' ESCAPE \'\\\'';
var search = '%' + (_.isString(restParams.q) ? escapeForLikePattern(_.toLower(restParams.q.trim())) : '') + '%';
var params = _.times(filterFields.length, _.constant(search));
return {
query: query,
params: params
};
}
function getConstrainedValues(data, constraints) {
var values = {};
_.each(_.keys(constraints), function (key) {
var value = data[key];
values[key] =
_.isUndefined(value) && !_.isUndefined(constraints[key].default) ? constraints[key].default : value;
});
return values;
}
const search = '%' + (_.isString(restParams.q) ? escapeForLikePattern(_.toLower(restParams.q.trim())) : '') + '%';
const params = _.times(filterFields.length, _.constant(search));
return {
getData: function (req) {
return _.extend({}, req.body, req.params, req.query);
},
query: query,
params: params
};
}
getValidRestParams: function(type, subtype, req, callback) {
var constraints = Constraints.rest[type];
if (!_.isPlainObject(constraints)) {
Logger.tag('validation', 'rest').error('Unknown REST resource type: {}', type);
function getConstrainedValues(data, constraints) {
const values = {};
_.each(_.keys(constraints), function (key) {
const value = data[key];
values[key] =
_.isUndefined(value) && !_.isUndefined(constraints[key].default) ? constraints[key].default : value;
});
return values;
}
module.exports = {
getData (req) {
return _.extend({}, req.body, req.params, req.query);
},
getValidRestParams(type, subtype, req, callback) {
const constraints = Constraints.rest[type];
if (!_.isPlainObject(constraints)) {
Logger.tag('validation', 'rest').error('Unknown REST resource type: {}', type);
return callback({data: 'Internal error.', type: ErrorTypes.internalError});
}
let filterConstraints = {};
if (subtype) {
filterConstraints = Constraints[subtype + 'Filters'];
if (!_.isPlainObject(filterConstraints)) {
Logger.tag('validation', 'rest').error('Unknown REST resource subtype: {}', subtype);
return callback({data: 'Internal error.', type: ErrorTypes.internalError});
}
var filterConstraints = {};
if (subtype) {
filterConstraints = Constraints[subtype + 'Filters'];
if (!_.isPlainObject(filterConstraints)) {
Logger.tag('validation', 'rest').error('Unknown REST resource subtype: {}', subtype);
return callback({data: 'Internal error.', type: ErrorTypes.internalError});
}
}
var data = this.getData(req);
var restParams = getConstrainedValues(data, constraints);
var filterParams = getConstrainedValues(data, filterConstraints);
var areValidParams = Validator.forConstraints(constraints);
var areValidFilters = Validator.forConstraints(filterConstraints);
if (!areValidParams(restParams) || !areValidFilters(filterParams)) {
return callback({data: 'Invalid REST parameters.', type: ErrorTypes.badRequest});
}
restParams.filters = filterParams;
callback(null, restParams);
},
filter: function (entities, allowedFilterFields, restParams) {
var query = restParams.q;
if (query) {
query = _.toLower(query.trim());
}
function queryMatches(entity) {
if (!query) {
return true;
}
return _.some(allowedFilterFields, function (field) {
var value = entity[field];
if (_.isNumber(value)) {
value = value.toString();
}
if (!_.isString(value) || _.isEmpty(value)) {
return false;
}
value = _.toLower(value);
if (field === 'mac') {
return _.includes(value.replace(/:/g, ''), query.replace(/:/g, ''));
}
return _.includes(value, query);
});
}
var filters = restParams.filters;
function filtersMatch(entity) {
if (_.isEmpty(filters)) {
return true;
}
return _.every(filters, function (value, key) {
if (_.isUndefined(value)) {
return true;
}
if (_.startsWith(key, 'has')) {
var entityKey = key.substr(3, 1).toLowerCase() + key.substr(4);
return _.isEmpty(entity[entityKey]).toString() !== value;
}
return entity[key] === value;
});
}
return _.filter(entities, function (entity) {
return queryMatches(entity) && filtersMatch(entity);
});
},
sort: function (entities, allowedSortFields, restParams) {
var sortField = _.includes(allowedSortFields, restParams._sortField) ? restParams._sortField : undefined;
if (!sortField) {
return entities;
}
var sorted = _.sortBy(entities, [sortField]);
return restParams._sortDir === 'ASC' ? sorted : _.reverse(sorted);
},
getPageEntities: function (entities, restParams) {
var page = restParams._page;
var perPage = restParams._perPage;
return entities.slice((page - 1) * perPage, page * perPage);
},
whereCondition: filterCondition,
filterClause: function (restParams, defaultSortField, allowedSortFields, filterFields) {
var orderBy = orderByClause(
restParams,
defaultSortField,
allowedSortFields
);
var limitOffset = limitOffsetClause(restParams);
var filter = filterCondition(
restParams,
filterFields
);
return {
query: filter.query + ' ' + orderBy.query + ' ' + limitOffset.query,
params: _.concat(filter.params, orderBy.params, limitOffset.params)
};
},
success: function (res, data) {
respond(res, 200, data, 'json');
},
successHtml: function (res, html) {
respond(res, 200, html, 'html');
},
error: function (res, err) {
respond(res, err.type.code, err.data, 'json');
}
};
});
const data = this.getData(req);
const restParams = getConstrainedValues(data, constraints);
const filterParams = getConstrainedValues(data, filterConstraints);
const areValidParams = Validator.forConstraints(constraints);
const areValidFilters = Validator.forConstraints(filterConstraints);
if (!areValidParams(restParams) || !areValidFilters(filterParams)) {
return callback({data: 'Invalid REST parameters.', type: ErrorTypes.badRequest});
}
restParams.filters = filterParams;
callback(null, restParams);
},
filter (entities, allowedFilterFields, restParams) {
let query = restParams.q;
if (query) {
query = _.toLower(query.trim());
}
function queryMatches(entity) {
if (!query) {
return true;
}
return _.some(allowedFilterFields, function (field) {
let value = entity[field];
if (_.isNumber(value)) {
value = value.toString();
}
if (!_.isString(value) || _.isEmpty(value)) {
return false;
}
value = _.toLower(value);
if (field === 'mac') {
return _.includes(value.replace(/:/g, ''), query.replace(/:/g, ''));
}
return _.includes(value, query);
});
}
const filters = restParams.filters;
function filtersMatch(entity) {
if (_.isEmpty(filters)) {
return true;
}
return _.every(filters, function (value, key) {
if (_.isUndefined(value)) {
return true;
}
if (_.startsWith(key, 'has')) {
const entityKey = key.substr(3, 1).toLowerCase() + key.substr(4);
return _.isEmpty(entity[entityKey]).toString() !== value;
}
return entity[key] === value;
});
}
return _.filter(entities, function (entity) {
return queryMatches(entity) && filtersMatch(entity);
});
},
sort (entities, allowedSortFields, restParams) {
const sortField = _.includes(allowedSortFields, restParams._sortField) ? restParams._sortField : undefined;
if (!sortField) {
return entities;
}
const sorted = _.sortBy(entities, [sortField]);
return restParams._sortDir === 'ASC' ? sorted : _.reverse(sorted);
},
getPageEntities (entities, restParams) {
const page = restParams._page;
const perPage = restParams._perPage;
return entities.slice((page - 1) * perPage, page * perPage);
},
whereCondition: filterCondition,
filterClause (restParams, defaultSortField, allowedSortFields, filterFields) {
const orderBy = orderByClause(
restParams,
defaultSortField,
allowedSortFields
);
const limitOffset = limitOffsetClause(restParams);
const filter = filterCondition(
restParams,
filterFields
);
return {
query: filter.query + ' ' + orderBy.query + ' ' + limitOffset.query,
params: _.concat(filter.params, orderBy.params, limitOffset.params)
};
},
success (res, data) {
respond(res, 200, data, 'json');
},
successHtml (res, html) {
respond(res, 200, html, 'html');
},
error (res, err) {
respond(res, err.type.code, err.data, 'json');
}
}

View file

@ -1,27 +1,27 @@
'use strict';
angular.module('ffffng').factory('Strings', function (_) {
return {
normalizeString: function (str) {
return _.isString(str) ? str.trim().replace(/\s+/g, ' ') : str;
},
const _ = require('lodash')
normalizeMac: function (mac) {
// parts only contains values at odd indexes
var parts = mac.toUpperCase().replace(/:/g, '').split(/([A-F0-9]{2})/);
module.exports = {
normalizeString (str) {
return _.isString(str) ? str.trim().replace(/\s+/g, ' ') : str;
},
var macParts = [];
normalizeMac (mac) {
// parts only contains values at odd indexes
const parts = mac.toUpperCase().replace(/:/g, '').split(/([A-F0-9]{2})/);
for (var i = 1; i < parts.length; i += 2) {
macParts.push(parts[i]);
}
const macParts = [];
return macParts.join(':');
},
parseInt: function (str) {
var parsed = _.parseInt(str, 10);
return parsed.toString() === str ? parsed : undefined;
for (let i = 1; i < parts.length; i += 2) {
macParts.push(parts[i]);
}
};
});
return macParts.join(':');
},
parseInt (str) {
const parsed = _.parseInt(str, 10);
return parsed.toString() === str ? parsed : undefined;
}
}

View file

@ -1,39 +1,41 @@
'use strict';
angular.module('ffffng').factory('UrlBuilder', function (_, config) {
function formUrl(route, queryParams) {
var url = config.server.baseUrl;
if (route || queryParams) {
url += '/#/';
}
if (route) {
url += route;
}
if (queryParams) {
url += '?';
url += _.join(
_.map(
queryParams,
function (value, key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(value);
}
),
'&'
);
}
return url;
const _ = require('lodash')
const config = require('../config').config
function formUrl(route, queryParams) {
let url = config.server.baseUrl;
if (route || queryParams) {
url += '/#/';
}
if (route) {
url += route;
}
if (queryParams) {
url += '?';
url += _.join(
_.map(
queryParams,
function (value, key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(value);
}
),
'&'
);
}
return url;
}
return {
editNodeUrl: function () {
return formUrl('update');
},
module.exports = {
editNodeUrl () {
return formUrl('update');
},
monitoringConfirmUrl: function (nodeSecrets) {
return formUrl('monitoring/confirm', { token: nodeSecrets.monitoringToken });
},
monitoringDisableUrl: function (nodeSecrets) {
return formUrl('monitoring/disable', { token: nodeSecrets.monitoringToken });
}
};
});
monitoringConfirmUrl (nodeSecrets) {
return formUrl('monitoring/confirm', { token: nodeSecrets.monitoringToken });
},
monitoringDisableUrl (nodeSecrets) {
return formUrl('monitoring/disable', { token: nodeSecrets.monitoringToken });
}
}