Typescript migration: Major refactoring.

This commit is contained in:
baldo 2020-04-10 00:43:15 +02:00
commit 52822207a5
31 changed files with 2068 additions and 2268 deletions

View file

@ -1,99 +0,0 @@
'use strict';
const Constraints = require('../validation/constraints')
const ErrorTypes = require('../utils/errorTypes')
const Logger = require('../logger')
const MailService = require('../services/mailService')
const Resources = require('../utils/resources')
const Strings = require('../utils/strings')
const Validator = require('../validation/validator')
const isValidId = Validator.forConstraint(Constraints.id);
function withValidMailId(req, res, callback) {
const id = Strings.normalizeString(Resources.getData(req).id);
if (!isValidId(id)) {
return callback({data: 'Invalid mail id.', type: ErrorTypes.badRequest});
}
callback(null, id);
}
module.exports = {
get (req, res) {
withValidMailId(req, res, function (err, id) {
if (err) {
return Resources.error(res, err);
}
MailService.getMail(id, function (err, mail) {
if (err) {
Logger.tag('mails', 'admin').error('Error getting mail:', err);
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
}
if (!mail) {
return Resources.error(res, {data: 'Mail not found.', type: ErrorTypes.notFound});
}
return Resources.success(res, mail);
});
});
},
getAll (req, res) {
Resources.getValidRestParams('list', null, req, function (err, restParams) {
if (err) {
return Resources.error(res, err);
}
return MailService.getPendingMails(
restParams,
function (err, mails, total) {
if (err) {
Logger.tag('mails', 'admin').error('Could not get pending mails:', err);
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
}
res.set('X-Total-Count', total);
return Resources.success(res, mails);
}
);
});
},
delete (req, res) {
withValidMailId(req, res, function (err, id) {
if (err) {
return Resources.error(res, err);
}
MailService.deleteMail(id, function (err) {
if (err) {
Logger.tag('mails', 'admin').error('Error deleting mail:', err);
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
}
return Resources.success(res);
});
});
},
resetFailures (req, res) {
withValidMailId(req, res, function (err, id) {
if (err) {
return Resources.error(res, err);
}
MailService.resetFailures(id, function (err, mail) {
if (err) {
Logger.tag('mails', 'admin').error('Error resetting failure count:', err);
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
}
return Resources.success(res, mail);
});
});
}
}

View file

@ -0,0 +1,67 @@
import CONSTRAINTS from "../validation/constraints";
import ErrorTypes from "../utils/errorTypes";
import * as MailService from "../services/mailService";
import * as Resources from "../utils/resources";
import {normalizeString} from "../utils/strings";
import {forConstraint} from "../validation/validator";
import {Request, Response} from "express";
import {Mail, MailId} from "../types";
const isValidId = forConstraint(CONSTRAINTS.id, false);
async function withValidMailId(req: Request): Promise<MailId> {
const id = normalizeString(Resources.getData(req).id);
if (!isValidId(id)) {
throw {data: 'Invalid mail id.', type: ErrorTypes.badRequest};
}
return id;
}
async function doGet(req: Request): Promise<Mail> {
const id = await withValidMailId(req);
return await MailService.getMail(id);
}
export function get(req: Request, res: Response): void {
doGet(req)
.then(mail => Resources.success(res, mail))
.catch(err => Resources.error(res, err))
}
async function doGetAll(req: Request): Promise<{total: number, mails: Mail[]}> {
const restParams = await Resources.getValidRestParams('list', null, req);
return await MailService.getPendingMails(restParams);
}
export function getAll (req: Request, res: Response): void {
doGetAll(req)
.then(({total, mails}) => {
res.set('X-Total-Count', total.toString(10));
return Resources.success(res, mails);
})
.catch(err => Resources.error(res, err))
}
async function doRemove(req: Request): Promise<void> {
const id = await withValidMailId(req);
await MailService.deleteMail(id);
}
export function remove (req: Request, res: Response): void {
doRemove(req)
.then(() => Resources.success(res, {}))
.catch(err => Resources.error(res, err));
}
async function doResetFailures(req: Request): Promise<Mail> {
const id = await withValidMailId(req);
return await MailService.resetFailures(id);
}
export function resetFailures (req: Request, res: Response): void {
doResetFailures(req)
.then(mail => Resources.success(res, mail))
.catch(err => Resources.error(res, err));
}

View file

@ -1,82 +0,0 @@
'use strict';
const _ = require('lodash')
const Constraints = require('../validation/constraints')
const ErrorTypes = require('../utils/errorTypes')
const Logger = require('../logger')
const MonitoringService = require('../services/monitoringService')
const Resources = require('../utils/resources')
const Strings = require('../utils/strings')
const Validator = require('../validation/validator')
const isValidToken = Validator.forConstraint(Constraints.token);
module.exports = {
getAll (req, res) {
Resources.getValidRestParams('list', null, req, function (err, restParams) {
if (err) {
return Resources.error(res, err);
}
return MonitoringService.getAll(
restParams,
function (err, monitoringStates, total) {
if (err) {
Logger.tag('monitoring', 'admin').error('Could not get monitoring states:', err);
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
}
res.set('X-Total-Count', total);
return Resources.success(res, _.map(monitoringStates, function (state) {
state.mapId = _.toLower(state.mac).replace(/:/g, '');
return state;
}));
}
);
});
},
confirm (req, res) {
const data = Resources.getData(req);
const token = Strings.normalizeString(data.token);
if (!isValidToken(token)) {
return Resources.error(res, {data: 'Invalid token.', type: ErrorTypes.badRequest});
}
return MonitoringService.confirm(token, function (err, node) {
if (err) {
return Resources.error(res, err);
}
return Resources.success(res, {
hostname: node.hostname,
mac: node.mac,
email: node.email,
monitoring: node.monitoring,
monitoringConfirmed: node.monitoringConfirmed
});
});
},
disable (req, res) {
const data = Resources.getData(req);
const token = Strings.normalizeString(data.token);
if (!isValidToken(token)) {
return Resources.error(res, {data: 'Invalid token.', type: ErrorTypes.badRequest});
}
return MonitoringService.disable(token, function (err, node) {
if (err) {
return Resources.error(res, err);
}
return Resources.success(res, {
hostname: node.hostname,
mac: node.mac,
email: node.email,
monitoring: node.monitoring
});
});
}
}

View file

@ -0,0 +1,69 @@
import _ from "lodash";
import CONSTRAINTS from "../validation/constraints";
import ErrorTypes from "../utils/errorTypes";
import * as MonitoringService from "../services/monitoringService";
import * as Resources from "../utils/resources";
import {normalizeString} from "../utils/strings";
import {forConstraint} from "../validation/validator";
import {Request, Response} from "express";
const isValidToken = forConstraint(CONSTRAINTS.token, false);
async function doGetAll(req: Request): Promise<{total: number, result: any}> {
const restParams = await Resources.getValidRestParams('list', null, req);
const {monitoringStates, total} = await MonitoringService.getAll(restParams);
return {
total,
result: _.map(monitoringStates, function (state) {
state.mapId = _.toLower(state.mac).replace(/:/g, '');
return state;
})
};
}
export function getAll(req: Request, res: Response): void {
doGetAll(req)
.then(({total, result}) => {
res.set('X-Total-Count', total.toString(10));
Resources.success(res, result)
})
.catch(err => Resources.error(res, err));
}
export function confirm(req: Request, res: Response): void {
const data = Resources.getData(req);
const token = normalizeString(data.token);
if (!isValidToken(token)) {
return Resources.error(res, {data: 'Invalid token.', type: ErrorTypes.badRequest});
}
MonitoringService.confirm(token)
.then(node => Resources.success(res, {
hostname: node.hostname,
mac: node.mac,
email: node.email,
monitoring: node.monitoring,
monitoringConfirmed: node.monitoringConfirmed
}))
.catch(err => Resources.error(res, err));
}
export function disable(req: Request, res: Response): void {
const data = Resources.getData(req);
const token = normalizeString(data.token);
if (!isValidToken(token)) {
return Resources.error(res, {data: 'Invalid token.', type: ErrorTypes.badRequest});
}
MonitoringService.disable(token)
.then(node => Resources.success(res, {
hostname: node.hostname,
mac: node.mac,
email: node.email,
monitoring: node.monitoring
}))
.catch(err => Resources.error(res, err));
}

View file

@ -1,181 +0,0 @@
'use strict';
const _ = require('lodash')
const deepExtend = require('deep-extend')
const Constraints = require('../validation/constraints')
const ErrorTypes = require('../utils/errorTypes')
const Logger = require('../logger')
const MonitoringService = require('../services/monitoringService')
const NodeService = require('../services/nodeService')
const Strings = require('../utils/strings')
const Validator = require('../validation/validator')
const Resources = require('../utils/resources')
const nodeFields = ['hostname', 'key', 'email', 'nickname', 'mac', 'coords', 'monitoring'];
function getNormalizedNodeData(reqData) {
const node = {};
_.each(nodeFields, function (field) {
let value = Strings.normalizeString(reqData[field]);
if (field === 'mac') {
value = Strings.normalizeMac(value);
}
node[field] = value;
});
return node;
}
const isValidNode = Validator.forConstraints(Constraints.node);
const isValidToken = Validator.forConstraint(Constraints.token);
module.exports = {
create: function (req, res) {
const data = Resources.getData(req);
const node = getNormalizedNodeData(data);
if (!isValidNode(node)) {
return Resources.error(res, {data: 'Invalid node data.', type: ErrorTypes.badRequest});
}
return NodeService.createNode(node, function (err, token, node) {
if (err) {
return Resources.error(res, err);
}
return Resources.success(res, {token: token, node: node});
});
},
update: function (req, res) {
const data = Resources.getData(req);
const token = Strings.normalizeString(data.token);
if (!isValidToken(token)) {
return Resources.error(res, {data: 'Invalid token.', type: ErrorTypes.badRequest});
}
const node = getNormalizedNodeData(data);
if (!isValidNode(node)) {
return Resources.error(res, {data: 'Invalid node data.', type: ErrorTypes.badRequest});
}
return NodeService.updateNode(token, node, function (err, token, node) {
if (err) {
return Resources.error(res, err);
}
return Resources.success(res, {token: token, node: node});
});
},
delete: function (req, res) {
const data = Resources.getData(req);
const token = Strings.normalizeString(data.token);
if (!isValidToken(token)) {
return Resources.error(res, {data: 'Invalid token.', type: ErrorTypes.badRequest});
}
return NodeService.deleteNode(token, function (err) {
if (err) {
return Resources.error(res, err);
}
return Resources.success(res, {});
});
},
get: function (req, res) {
const token = Strings.normalizeString(Resources.getData(req).token);
if (!isValidToken(token)) {
return Resources.error(res, {data: 'Invalid token.', type: ErrorTypes.badRequest});
}
return NodeService.getNodeDataByToken(token, function (err, node) {
if (err) {
return Resources.error(res, err);
}
return Resources.success(res, node);
});
},
getAll: function (req, res) {
Resources.getValidRestParams('list', 'node', req, function (err, restParams) {
if (err) {
return Resources.error(res, err);
}
return NodeService.getAllNodes(function (err, nodes) {
if (err) {
return Resources.error(res, err);
}
const realNodes = _.filter(nodes, function (node) {
// We ignore nodes without tokens as those are only manually added ones like gateways.
return node.token;
});
const macs = _.map(realNodes, function (node) {
return node.mac;
});
MonitoringService.getByMacs(macs, function (err, nodeStateByMac) {
if (err) {
Logger.tag('nodes', 'admin').error('Error getting nodes by MACs:', err);
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
}
const enhancedNodes = _.map(realNodes, function (node) {
const nodeState = nodeStateByMac[node.mac];
if (nodeState) {
return deepExtend({}, node, {
site: nodeState.site,
domain: nodeState.domain,
onlineState: nodeState.state
});
}
return node;
});
const filteredNodes = Resources.filter(
enhancedNodes,
[
'hostname',
'nickname',
'email',
'token',
'mac',
'site',
'domain',
'key',
'onlineState'
],
restParams
);
const total = filteredNodes.length;
const sortedNodes = Resources.sort(
filteredNodes,
[
'hostname',
'nickname',
'email',
'token',
'mac',
'key',
'site',
'domain',
'coords',
'onlineState',
'monitoringState'
],
restParams
);
const pageNodes = Resources.getPageEntities(sortedNodes, restParams);
res.set('X-Total-Count', total);
return Resources.success(res, pageNodes);
});
});
});
}
}

View file

@ -0,0 +1,160 @@
import _ from "lodash";
import deepExtend from "deep-extend";
import Constraints from "../validation/constraints";
import ErrorTypes from "../utils/errorTypes";
import * as MonitoringService from "../services/monitoringService";
import * as NodeService from "../services/nodeService";
import {normalizeMac, normalizeString} from "../utils/strings";
import {forConstraint, forConstraints} from "../validation/validator";
import * as Resources from "../utils/resources";
import {Entity} from "../utils/resources";
import {Request, Response} from "express";
import {Node} from "../types";
const nodeFields = ['hostname', 'key', 'email', 'nickname', 'mac', 'coords', 'monitoring'];
function getNormalizedNodeData(reqData: any): Node {
const node: {[key: string]: any} = {};
_.each(nodeFields, function (field) {
let value = normalizeString(reqData[field]);
if (field === 'mac') {
value = normalizeMac(value);
}
node[field] = value;
});
return node as Node;
}
const isValidNode = forConstraints(Constraints.node, false);
const isValidToken = forConstraint(Constraints.token, false);
export function create (req: Request, res: Response): void {
const data = Resources.getData(req);
const node = getNormalizedNodeData(data);
if (!isValidNode(node)) {
return Resources.error(res, {data: 'Invalid node data.', type: ErrorTypes.badRequest});
}
NodeService.createNode(node)
.then(result => Resources.success(res, result))
.catch(err => Resources.error(res, err));
}
export function update (req: Request, res: Response): void {
const data = Resources.getData(req);
const token = normalizeString(data.token);
if (!isValidToken(token)) {
return Resources.error(res, {data: 'Invalid token.', type: ErrorTypes.badRequest});
}
const node = getNormalizedNodeData(data);
if (!isValidNode(node)) {
return Resources.error(res, {data: 'Invalid node data.', type: ErrorTypes.badRequest});
}
NodeService.updateNode(token, node)
.then(result => Resources.success(res, result))
.catch(err => Resources.error(res, err));
}
export function remove(req: Request, res: Response): void {
const data = Resources.getData(req);
const token = normalizeString(data.token);
if (!isValidToken(token)) {
return Resources.error(res, {data: 'Invalid token.', type: ErrorTypes.badRequest});
}
NodeService.deleteNode(token)
.then(() => Resources.success(res, {}))
.catch(err => Resources.error(res, err));
}
export function get(req: Request, res: Response): void {
const token = normalizeString(Resources.getData(req).token);
if (!isValidToken(token)) {
return Resources.error(res, {data: 'Invalid token.', type: ErrorTypes.badRequest});
}
NodeService.getNodeDataByToken(token)
.then(node => Resources.success(res, node))
.catch(err => Resources.error(res, err));
}
async function doGetAll(req: Request): Promise<{ total: number; pageNodes: any }> {
const restParams = await Resources.getValidRestParams('list', 'node', req);
const nodes = await NodeService.getAllNodes();
const realNodes = _.filter(nodes, node =>
// We ignore nodes without tokens as those are only manually added ones like gateways.
!!node.token
);
const macs = _.map(realNodes, (node: Node): string => node.mac);
const nodeStateByMac = await MonitoringService.getByMacs(macs);
const enhancedNodes: Entity[] = _.map(realNodes, (node: Node) => {
const nodeState = nodeStateByMac[node.mac];
if (nodeState) {
return deepExtend({}, node, {
site: nodeState.site,
domain: nodeState.domain,
onlineState: nodeState.state
});
}
return node;
});
const filteredNodes = Resources.filter(
enhancedNodes,
[
'hostname',
'nickname',
'email',
'token',
'mac',
'site',
'domain',
'key',
'onlineState'
],
restParams
);
const total = filteredNodes.length;
const sortedNodes = Resources.sort(
filteredNodes,
[
'hostname',
'nickname',
'email',
'token',
'mac',
'key',
'site',
'domain',
'coords',
'onlineState',
'monitoringState'
],
restParams
);
const pageNodes = Resources.getPageEntities(sortedNodes, restParams);
return {total, pageNodes};
}
export function getAll(req: Request, res: Response): void {
doGetAll(req)
.then((result: {total: number, pageNodes: any[]}) => {
res.set('X-Total-Count', result.total.toString(10));
return Resources.success(res, result.pageNodes);
})
.catch((err: any) => Resources.error(res, err));
}

View file

@ -1,24 +0,0 @@
'use strict';
const ErrorTypes = require('../utils/errorTypes')
const Logger = require('../logger')
const NodeService = require('../services/nodeService')
const Resources = require('../utils/resources')
module.exports = {
get (req, res) {
NodeService.getNodeStatistics((err, nodeStatistics) => {
if (err) {
Logger.tag('statistics').error('Error getting statistics:', err);
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
}
return Resources.success(
res,
{
nodes: nodeStatistics
}
);
});
}
}

View file

@ -0,0 +1,20 @@
import ErrorTypes from "../utils/errorTypes";
import Logger from "../logger";
import {getNodeStatistics} from "../services/nodeService";
import * as Resources from "../utils/resources";
import {Request, Response} from "express";
export function get (req: Request, res: Response): void {
// TODO: Promises and types.
getNodeStatistics()
.then(nodeStatistics => Resources.success(
res,
{
nodes: nodeStatistics
}
))
.catch(err => {
Logger.tag('statistics').error('Error getting statistics:', err);
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
});
}

View file

@ -7,6 +7,7 @@ import {getTasks, Task} from "../jobs/scheduler";
import {normalizeString} from "../utils/strings";
import {forConstraint} from "../validation/validator";
import {Request, Response} from "express";
import {Entity} from "../utils/resources";
const isValidId = forConstraint(CONSTRAINTS.id, false);
@ -71,39 +72,36 @@ function setTaskEnabled(req: Request, res: Response, enable: boolean) {
.catch(err => Resources.error(res, err))
}
async function doGetAll(req: Request): Promise<{total: number, pageTasks: Entity[]}> {
const restParams = await Resources.getValidRestParams('list', null, req);
const tasks = Resources.sort(
_.values(getTasks()),
['id', 'name', 'schedule', 'state', 'runningSince', 'lastRunStarted'],
restParams
);
const filteredTasks = Resources.filter(
tasks,
['id', 'name', 'schedule', 'state'],
restParams
);
const total = filteredTasks.length;
const pageTasks = Resources.getPageEntities(filteredTasks, restParams);
return {
total,
pageTasks,
};
}
export function getAll (req: Request, res: Response): void {
Resources.getValidRestParams('list', null, req, function (err, restParams) {
if (err) {
return Resources.error(res, err);
}
if (!restParams) {
return Resources.error(
res,
{
data: "Unexpected state: restParams is not set.",
type: ErrorTypes.internalError
}
);
}
const tasks = Resources.sort(
_.values(getTasks()),
['id', 'name', 'schedule', 'state', 'runningSince', 'lastRunStarted'],
restParams
);
const filteredTasks = Resources.filter(
tasks,
['id', 'name', 'schedule', 'state'],
restParams
);
const total = filteredTasks.length;
const pageTasks = Resources.getPageEntities(filteredTasks, restParams);
res.set('X-Total-Count', total.toString(10));
return Resources.success(res, _.map(pageTasks, toExternalTask));
});
doGetAll(req)
.then(({total, pageTasks}) => {
res.set('X-Total-Count', total.toString(10));
Resources.success(res, _.map(pageTasks, toExternalTask));
})
.catch(err => Resources.error(res, err));
}
export function run (req: Request, res: Response): void {