Removing ng-di on the server.

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

View file

@ -33,7 +33,6 @@
"lodash": "^4.17.11",
"moment": "^2.22.2",
"ng-admin": "^1.0.13",
"ng-di": "^0.2.1",
"node-cron": "^2.0.1",
"nodemailer": "^4.6.8",
"nodemailer-html-to-text": "^3.0.0",

View file

@ -1,16 +1,21 @@
'use strict';
angular.module('ffffng').factory('app', function (fs, config, _) {
var express = require('express');
var auth = require('http-auth');
var bodyParser = require('body-parser');
var compress = require('compression');
const _ = require('lodash')
const auth = require('http-auth');
const bodyParser = require('body-parser');
const compress = require('compression');
const express = require('express');
const fs = require('graceful-fs')
var app = express();
var router = express.Router();
const config = require('./config').config
const app = express();
module.exports = (() => {
const router = express.Router();
// urls beneath /internal are protected
var internalAuth = auth.basic(
const internalAuth = auth.basic(
{
realm: 'Knotenformular - Intern'
},
@ -27,24 +32,24 @@ angular.module('ffffng').factory('app', function (fs, config, _) {
router.use(bodyParser.json());
router.use(bodyParser.urlencoded({ extended: true }));
var adminDir = __dirname + '/../admin';
var clientDir = __dirname + '/../client';
var templateDir = __dirname + '/templates';
const adminDir = __dirname + '/../admin';
const clientDir = __dirname + '/../client';
const templateDir = __dirname + '/templates';
var jsTemplateFiles = [
const jsTemplateFiles = [
'/config.js'
];
router.use(compress());
function serveTemplate(mimeType, req, res, next) {
function serveTemplate (mimeType, req, res, next) {
return fs.readFile(templateDir + '/' + req.path, 'utf8', function (err, body) {
if (err) {
return next(err);
}
res.writeHead(200, {'Content-Type': mimeType});
res.end(_.template(body)( { config: config.client }));
res.writeHead(200, { 'Content-Type': mimeType });
res.end(_.template(body)({ config: config.client }));
return null; // to suppress warning
});
@ -63,4 +68,4 @@ angular.module('ffffng').factory('app', function (fs, config, _) {
app.use(config.server.rootPath, router);
return app;
});
})()

View file

@ -1,156 +1,158 @@
'use strict';
var commandLineArgs = require('command-line-args');
var commandLineUsage = require('command-line-usage');
module.exports = (() => {
const commandLineArgs = require('command-line-args');
const commandLineUsage = require('command-line-usage');
var commandLineDefs = [
{ name: 'help', alias: 'h', type: Boolean, description: 'Show this help' },
{ name: 'config', alias: 'c', type: String, description: 'Location of config.json' },
{ name: 'version', alias: 'v', type: Boolean, description: 'Show ffffng version' }
];
const commandLineDefs = [
{ name: 'help', alias: 'h', type: Boolean, description: 'Show this help' },
{ name: 'config', alias: 'c', type: String, description: 'Location of config.json' },
{ name: 'version', alias: 'v', type: Boolean, description: 'Show ffffng version' }
];
var commandLineOptions;
try {
commandLineOptions = commandLineArgs(commandLineDefs);
} catch (e) {
console.error(e.message);
console.error('Try \'--help\' for more information.');
process.exit(1);
}
let commandLineOptions;
try {
commandLineOptions = commandLineArgs(commandLineDefs);
} catch (e) {
console.error(e.message);
console.error('Try \'--help\' for more information.');
process.exit(1);
}
var fs = require('graceful-fs');
const fs = require('graceful-fs');
var packageJsonFile = __dirname + '/../package.json';
var version = 'unknown';
if (fs.existsSync(packageJsonFile)) {
version = JSON.parse(fs.readFileSync(packageJsonFile, 'utf8')).version;
}
const packageJsonFile = __dirname + '/../package.json';
let version = 'unknown';
if (fs.existsSync(packageJsonFile)) {
version = JSON.parse(fs.readFileSync(packageJsonFile, 'utf8')).version;
}
function usage() {
console.log(commandLineUsage([
{
header: 'ffffng - ' + version + ' - Freifunk node management form',
optionList: commandLineDefs
}
]));
}
function usage () {
console.log(commandLineUsage([
{
header: 'ffffng - ' + version + ' - Freifunk node management form',
optionList: commandLineDefs
}
]));
}
if (commandLineOptions.help) {
usage();
process.exit(0);
}
if (commandLineOptions.help) {
usage();
process.exit(0);
}
if (commandLineOptions.version) {
console.log('ffffng - ' + version);
process.exit(0);
}
if (commandLineOptions.version) {
console.log('ffffng - ' + version);
process.exit(0);
}
if (!commandLineOptions.config) {
usage();
process.exit(1);
}
if (!commandLineOptions.config) {
usage();
process.exit(1);
}
var deepExtend = require('deep-extend');
const deepExtend = require('deep-extend');
var defaultConfig = {
server: {
baseUrl: 'http://localhost:8080',
port: 8080,
const defaultConfig = {
server: {
baseUrl: 'http://localhost:8080',
port: 8080,
databaseFile: '/tmp/ffffng.sqlite',
peersPath: '/tmp/peers',
databaseFile: '/tmp/ffffng.sqlite',
peersPath: '/tmp/peers',
logging: {
directory: '/tmp/logs',
debug: false,
profile: false,
logRequests: false
},
logging: {
directory: '/tmp/logs',
debug: false,
profile: false,
logRequests: false
},
internal: {
active: false,
user: 'admin',
password: 'secret'
},
internal: {
active: false,
user: 'admin',
password: 'secret'
},
email: {
from: 'Freifunk Knotenformular <no-reply@musterstadt.freifunk.net>',
email: {
from: 'Freifunk Knotenformular <no-reply@musterstadt.freifunk.net>',
// For details see: https://nodemailer.com/2-0-0-beta/setup-smtp/
smtp: {
host: 'mail.example.com',
port: '465',
secure: true,
auth: {
user: 'user@example.com',
pass: 'pass'
// For details see: https://nodemailer.com/2-0-0-beta/setup-smtp/
smtp: {
host: 'mail.example.com',
port: '465',
secure: true,
auth: {
user: 'user@example.com',
pass: 'pass'
}
}
},
map: {
nodesJsonUrl: ['http://map.musterstadt.freifunk.net/nodes.json']
}
},
map: {
nodesJsonUrl: ['http://map.musterstadt.freifunk.net/nodes.json']
client: {
community: {
name: 'Freifunk Musterstadt',
domain: 'musterstadt.freifunk.net',
contactEmail: 'kontakt@musterstadt.freifunk.net',
sites: [],
domains: []
},
legal: {
privacyUrl: null,
imprintUrl: null
},
map: {
mapUrl: 'http://map.musterstadt.freifunk.net'
},
monitoring: {
enabled: false
},
coordsSelector: {
showInfo: false,
showBorderForDebugging: false,
localCommunityPolygon: [],
lat: 53.565278,
lng: 10.001389,
defaultZoom: 10,
layers: {}
}
}
},
client: {
community: {
name: 'Freifunk Musterstadt',
domain: 'musterstadt.freifunk.net',
contactEmail: 'kontakt@musterstadt.freifunk.net',
sites: [],
domains: []
},
legal: {
privacyUrl: null,
imprintUrl: null
},
map: {
mapUrl: 'http://map.musterstadt.freifunk.net'
},
monitoring: {
enabled: false
},
coordsSelector: {
showInfo: false,
showBorderForDebugging: false,
localCommunityPolygon: [],
lat: 53.565278,
lng: 10.001389,
defaultZoom: 10,
layers: {}
};
const configJSONFile = commandLineOptions.config;
let configJSON = {};
if (fs.existsSync(configJSONFile)) {
configJSON = JSON.parse(fs.readFileSync(configJSONFile, 'utf8'));
} else {
console.error('config.json not found: ' + configJSONFile);
process.exit(1);
}
const _ = require('lodash');
function stripTrailingSlash (obj, field) {
const url = obj[field];
if (_.isString(url) && _.last(url) === '/') {
obj[field] = url.substr(0, url.length - 1);
}
}
};
var configJSONFile = commandLineOptions.config;
var configJSON = {};
const config = deepExtend({}, defaultConfig, configJSON);
if (fs.existsSync(configJSONFile)) {
configJSON = JSON.parse(fs.readFileSync(configJSONFile, 'utf8'));
} else {
console.error('config.json not found: ' + configJSONFile);
process.exit(1);
}
stripTrailingSlash(config.server, 'baseUrl');
stripTrailingSlash(config.client.map, 'mapUrl');
var _ = require('lodash');
const url = require('url');
config.server.rootPath = url.parse(config.server.baseUrl).pathname;
config.client.rootPath = config.server.rootPath;
function stripTrailingSlash(obj, field) {
var url = obj[field];
if (_.isString(url) && _.last(url) === '/') {
obj[field] = url.substr(0, url.length - 1);
return {
config,
version
}
}
var config = deepExtend({}, defaultConfig, configJSON);
stripTrailingSlash(config.server, 'baseUrl');
stripTrailingSlash(config.client.map, 'mapUrl');
var url = require('url');
config.server.rootPath = url.parse(config.server.baseUrl).pathname;
config.client.rootPath = config.server.rootPath;
module.exports = config;
angular.module('ffffng').constant('config', config);
angular.module('ffffng').constant('version', version);
})()

View file

@ -5,7 +5,7 @@ const fs = require('graceful-fs');
const glob = util.promisify(require('glob'));
const path = require('path');
const config = require('../config');
const config = require('../config').config;
const Logger = require('../logger');
async function applyPatch(db, file) {
@ -72,10 +72,7 @@ async function init() {
throw error;
}
// WARNING: We have to use funtion() syntax here, to satisfy ng-di. m(
return angular.module('ffffng').factory('Database', function () {
return db;
});
module.exports.db = db;
}
module.exports = {

View file

@ -0,0 +1,18 @@
'use strict';
const Logger = require('../logger')
const NodeService = require('../services/nodeService')
module.exports = {
description: 'Makes sure node files (holding fastd key, name, etc.) are correctly named.',
run: function (callback) {
NodeService.fixNodeFilenames(function (err) {
if (err) {
Logger.tag('nodes', 'fix-filenames').error('Error fixing filenames:', err);
}
callback();
});
}
}

View file

@ -0,0 +1,18 @@
'use strict';
const Logger = require('../logger')
const MailService = require('../services/mailService')
module.exports = {
description: 'Send pending emails (up to 5 attempts in case of failures).',
run: function (callback) {
MailService.sendPendingMails(function (err) {
if (err) {
Logger.tag('mail', 'queue').error('Error sending pending mails:', err);
}
callback();
});
}
}

View file

@ -0,0 +1,18 @@
'use strict';
const Logger = require('../logger')
const MonitoringService = require('../services/monitoringService')
module.exports = {
description: 'Sends monitoring emails depending on the monitoring state of nodes retrieved by the NodeInformationRetrievalJob.',
run: function (callback) {
MonitoringService.sendMonitoringMails(function (err) {
if (err) {
Logger.tag('monitoring', 'mail-sending').error('Error sending monitoring mails:', err);
}
callback();
});
}
}

View file

@ -0,0 +1,18 @@
'use strict';
const Logger = require('../logger')
const MonitoringService = require('../services/monitoringService')
module.exports = {
description: 'Fetches the nodes.json and calculates and stores the monitoring / online status for registered nodes.',
run: function (callback) {
MonitoringService.retrieveNodeInformation(function (err) {
if (err) {
Logger.tag('monitoring', 'information-retrieval').error('Error retrieving node data:', err);
}
callback();
});
}
}

View file

@ -0,0 +1,18 @@
'use strict';
const Logger = require('../logger')
const MonitoringService = require('../services/monitoringService')
module.exports = {
description: 'Delete nodes that are offline for more than 100 days.',
run: function (callback) {
MonitoringService.deleteOfflineNodes(function (err) {
if (err) {
Logger.tag('nodes', 'delete-offline').error('Error deleting offline nodes:', err);
}
callback();
});
}
}

View file

@ -1,17 +0,0 @@
'use strict';
angular.module('ffffng').factory('FixNodeFilenamesJob', function (NodeService, Logger) {
return {
description: 'Makes sure node files (holding fastd key, name, etc.) are correctly named.',
run: function (callback) {
NodeService.fixNodeFilenames(function (err) {
if (err) {
Logger.tag('nodes', 'fix-filenames').error('Error fixing filenames:', err);
}
callback();
});
}
};
});

View file

@ -1,17 +0,0 @@
'use strict';
angular.module('ffffng').factory('MailQueueJob', function (MailService, Logger) {
return {
description: 'Send pending emails (up to 5 attempts in case of failures).',
run: function (callback) {
MailService.sendPendingMails(function (err) {
if (err) {
Logger.tag('mail', 'queue').error('Error sending pending mails:', err);
}
callback();
});
}
};
});

View file

@ -1,17 +0,0 @@
'use strict';
angular.module('ffffng').factory('MonitoringMailsSendingJob', function (MonitoringService, Logger) {
return {
description: 'Sends monitoring emails depending on the monitoring state of nodes retrieved by the NodeInformationRetrievalJob.',
run: function (callback) {
MonitoringService.sendMonitoringMails(function (err) {
if (err) {
Logger.tag('monitoring', 'mail-sending').error('Error sending monitoring mails:', err);
}
callback();
});
}
};
});

View file

@ -1,17 +0,0 @@
'use strict';
angular.module('ffffng').factory('NodeInformationRetrievalJob', function (MonitoringService, Logger) {
return {
description: 'Fetches the nodes.json and calculates and stores the monitoring / online status for registered nodes.',
run: function (callback) {
MonitoringService.retrieveNodeInformation(function (err) {
if (err) {
Logger.tag('monitoring', 'information-retrieval').error('Error retrieving node data:', err);
}
callback();
});
}
};
});

View file

@ -1,17 +0,0 @@
'use strict';
angular.module('ffffng').factory('OfflineNodesDeletionJob', function (MonitoringService, Logger) {
return {
description: 'Delete nodes that are offline for more than 100 days.',
run: function (callback) {
MonitoringService.deleteOfflineNodes(function (err) {
if (err) {
Logger.tag('nodes', 'delete-offline').error('Error deleting offline nodes:', err);
}
callback();
});
}
};
});

View file

@ -1,98 +1,99 @@
'use strict';
var glob = require('glob');
var _ = require('lodash');
const _ = require('lodash');
const cron = require('node-cron');
const glob = require('glob');
const moment = require('moment');
var jobFiles = glob.sync(__dirname + '/*Job.js');
const config = require('../config').config
const Logger = require('../logger')
const jobFiles = glob.sync(__dirname + '/*Job.js');
_.each(jobFiles, function (jobFile) {
require(jobFile);
});
angular.module('ffffng').factory('Scheduler', function ($injector, Logger, config, moment) {
var cron = require('node-cron');
const tasks = {};
var tasks = {};
let taskId = 1;
function nextTaskId() {
const id = taskId;
taskId += 1;
return id;
}
var taskId = 1;
function nextTaskId() {
var id = taskId;
taskId += 1;
return id;
function schedule(expr, jobName) {
Logger.tag('jobs').info('Scheduling job: %s %s', expr, jobName);
var job = require(`../jobs/${jobName}`);
if (!_.isFunction(job.run)) {
throw new Error('The job ' + jobName + ' does not provide a "run" function.');
}
function schedule(expr, jobName) {
Logger.tag('jobs').info('Scheduling job: %s %s', expr, jobName);
var job = $injector.get(jobName);
if (!_.isFunction(job.run)) {
throw new Error('The job ' + jobName + ' does not provide a "run" function.');
}
var id = nextTaskId();
var task = {
id: id,
name: jobName,
description: job.description,
schedule: expr,
job: job,
runningSince: false,
lastRunStarted: false,
lastRunDuration: null,
state: 'idle',
enabled: true
};
task.run = function () {
if (task.runningSince || !task.enabled) {
// job is still running, skip execution
return;
}
task.runningSince = moment();
task.lastRunStarted = task.runningSince;
task.state = 'running';
job.run(function () {
var now = moment();
var duration = now.diff(task.runningSince);
Logger.tag('jobs').profile('[%sms]\t%s', duration, task.name);
task.runningSince = false;
task.lastRunDuration = duration;
task.state = 'idle';
});
};
cron.schedule(expr, task.run);
tasks['' + id] = task;
}
return {
init: function () {
Logger.tag('jobs').info('Scheduling background jobs...');
try {
schedule('0 */1 * * * *', 'MailQueueJob');
schedule('15 */1 * * * *', 'FixNodeFilenamesJob');
if (config.client.monitoring.enabled) {
schedule('30 */15 * * * *', 'NodeInformationRetrievalJob');
schedule('45 */5 * * * *', 'MonitoringMailsSendingJob');
schedule('0 0 3 * * *', 'OfflineNodesDeletionJob'); // every night at 3:00
}
}
catch (error) {
Logger.tag('jobs').error('Error during scheduling of background jobs:', error);
throw error;
}
Logger.tag('jobs').info('Scheduling of background jobs done.');
},
getTasks: function () {
return tasks;
}
var id = nextTaskId();
var task = {
id: id,
name: jobName,
description: job.description,
schedule: expr,
job: job,
runningSince: false,
lastRunStarted: false,
lastRunDuration: null,
state: 'idle',
enabled: true
};
});
task.run = function () {
if (task.runningSince || !task.enabled) {
// job is still running, skip execution
return;
}
task.runningSince = moment();
task.lastRunStarted = task.runningSince;
task.state = 'running';
job.run(function () {
var now = moment();
var duration = now.diff(task.runningSince);
Logger.tag('jobs').profile('[%sms]\t%s', duration, task.name);
task.runningSince = false;
task.lastRunDuration = duration;
task.state = 'idle';
});
};
cron.schedule(expr, task.run);
tasks['' + id] = task;
}
module.exports = {
init: function () {
Logger.tag('jobs').info('Scheduling background jobs...');
try {
schedule('0 */1 * * * *', 'MailQueueJob');
schedule('15 */1 * * * *', 'FixNodeFilenamesJob');
if (config.client.monitoring.enabled) {
schedule('30 */15 * * * *', 'NodeInformationRetrievalJob');
schedule('45 */5 * * * *', 'MonitoringMailsSendingJob');
schedule('0 0 3 * * *', 'OfflineNodesDeletionJob'); // every night at 3:00
}
}
catch (error) {
Logger.tag('jobs').error('Error during scheduling of background jobs:', error);
throw error;
}
Logger.tag('jobs').info('Scheduling of background jobs done.');
},
getTasks: function () {
return tasks;
}
}

View file

@ -1,24 +0,0 @@
'use strict';
(function () {
var module = angular.module('ffffng');
function lib(name, nodeModule) {
if (!nodeModule) {
nodeModule = name;
}
module.factory(name, function () {
return require(nodeModule);
});
}
lib('_', 'lodash');
lib('async');
lib('crypto');
lib('deepExtend', 'deep-extend');
lib('fs', 'graceful-fs');
lib('glob');
lib('moment');
lib('request');
})();

View file

@ -1,7 +1,7 @@
'use strict';
var config = require('./config');
const app = require('./app');
const config = require('./config').config;
// Hack to allow proper logging of Error.
Object.defineProperty(Error.prototype, 'message', {
@ -14,7 +14,7 @@ Object.defineProperty(Error.prototype, 'stack', {
});
var scribe = require('scribe-js')({
const scribe = require('scribe-js')({
rootPath: config.server.logging.directory,
});
@ -33,30 +33,26 @@ function addLogger(name, color, active) {
addLogger('debug', 'grey', config.server.logging.debug);
addLogger('profile', 'blue', config.server.logging.profile);
angular.module('ffffng').factory('Logger', function (app) {
if (config.server.logging.logRequests) {
app.use(scribe.express.logger());
}
if (config.server.internal.active) {
var prefix = config.server.rootPath === '/' ? '' : config.server.rootPath;
app.use(prefix + '/internal/logs', scribe.webPanel());
}
if (config.server.logging.logRequests) {
app.use(scribe.express.logger());
}
if (config.server.internal.active) {
const prefix = config.server.rootPath === '/' ? '' : config.server.rootPath;
app.use(prefix + '/internal/logs', scribe.webPanel());
}
// Hack to allow correct logging of node.js Error objects.
// See: https://github.com/bluejamesbond/Scribe.js/issues/70
Object.defineProperty(Error.prototype, 'toJSON', {
configurable: true,
value: function () {
var alt = {};
var storeKey = function (key) {
alt[key] = this[key];
};
Object.getOwnPropertyNames(this).forEach(storeKey, this);
return alt;
}
});
return process.console;
// Hack to allow correct logging of node.js Error objects.
// See: https://github.com/bluejamesbond/Scribe.js/issues/70
Object.defineProperty(Error.prototype, 'toJSON', {
configurable: true,
value: function () {
const alt = {};
const storeKey = function (key) {
alt[key] = this[key];
};
Object.getOwnPropertyNames(this).forEach(storeKey, this);
return alt;
}
});
module.exports = process.console;

View file

@ -2,11 +2,6 @@
/*jslint node: true */
'use strict';
// Dirty hack to allow usage of angular modules.
global.angular = require('ng-di');
angular.module('ffffng', []);
(function () {
// Use graceful-fs instead of fs also in all libraries to have more robust fs handling.
const realFs = require('fs');
@ -14,52 +9,24 @@ angular.module('ffffng', []);
gracefulFs.gracefulify(realFs);
})();
require('./config');
const config = require('./config').config;
require('./logger').tag('main', 'startup').info('Server starting up...');
const Logger = require('./logger')
Logger.tag('main', 'startup').info('Server starting up...');
require('./app');
require('./router');
require('./libs');
require('./db/database').init()
.then(() => {
Logger.tag('main').info('Initializing...');
require('./utils/databaseUtil');
require('./utils/errorTypes');
require('./utils/resources');
require('./utils/strings');
require('./utils/urlBuilder');
const app = require('./app');
require('./resources/versionResource');
require('./resources/statisticsResource');
require('./resources/frontendResource');
require('./resources/taskResource');
require('./resources/mailResource');
require('./resources/nodeResource');
require('./resources/monitoringResource');
require('./jobs/scheduler').init();
require('./router').init();
require('./services/mailService');
require('./services/mailTemplateService');
require('./services/nodeService');
require('./services/monitoringService');
require('../shared/validation/constraints');
require('./validation/validator');
require('./jobs/scheduler');
const db = require('./db/database');
db.init().then(() => {
// WARNING: We have to use funtion() syntax here, to satisfy ng-di. m(
angular.injector(['ffffng']).invoke(function (config, app, Logger, Scheduler, Router) {
Logger.tag('main').info('Initializing...');
Scheduler.init();
Router.init();
app.listen(config.server.port, '::');
module.exports = app;
});
}).catch(error => {
app.listen(config.server.port, '::');
module.exports = app;
})
.catch(error => {
console.error('Could not init database: ', error);
process.exit(1);
});

View file

@ -1,31 +1,30 @@
'use strict';
angular.module('ffffng').factory('FrontendResource', function (
Logger,
Resources,
ErrorTypes,
fs
) {
var indexHtml = __dirname + '/../../client/index.html';
const fs = require('graceful-fs')
return {
render: function (req, res) {
var data = Resources.getData(req);
const ErrorTypes = require('../utils/errorTypes')
const Logger = require('../logger')
const Resources = require('../utils/resources')
fs.readFile(indexHtml, 'utf8', function (err, body) {
if (err) {
Logger.tag('frontend').error('Could not read file: ', indexHtml, err);
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
}
const indexHtml = __dirname + '/../../client/index.html';
return Resources.successHtml(
res,
body.replace(
/<body/,
'<script>window.__nodeToken = \''+ data.token + '\';</script><body'
)
);
});
}
};
});
module.exports = {
render (req, res) {
const data = Resources.getData(req);
fs.readFile(indexHtml, 'utf8', function (err, body) {
if (err) {
Logger.tag('frontend').error('Could not read file: ', indexHtml, err);
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
}
return Resources.successHtml(
res,
body.replace(
/<body/,
'<script>window.__nodeToken = \''+ data.token + '\';</script><body'
)
);
});
}
}

View file

@ -1,101 +1,99 @@
'use strict';
angular.module('ffffng').factory('MailResource', function (
Constraints,
Validator,
MailService,
Resources,
Logger,
ErrorTypes,
Strings
) {
var isValidId = Validator.forConstraint(Constraints.id);
const Constraints = require('../../shared/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')
function withValidMailId(req, res, callback) {
var id = Strings.normalizeString(Resources.getData(req).id);
const isValidId = Validator.forConstraint(Constraints.id);
if (!isValidId(id)) {
return callback({data: 'Invalid mail id.', type: ErrorTypes.badRequest});
}
function withValidMailId(req, res, callback) {
const id = Strings.normalizeString(Resources.getData(req).id);
callback(null, id);
if (!isValidId(id)) {
return callback({data: 'Invalid mail id.', type: ErrorTypes.badRequest});
}
return {
get: function (req, res) {
withValidMailId(req, res, function (err, id) {
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) {
return Resources.error(res, err);
Logger.tag('mails', 'admin').error('Error getting mail:', err);
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
}
MailService.getMail(id, function (err, mail) {
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('Error getting mail:', err);
Logger.tag('mails', 'admin').error('Could not get pending mails:', err);
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
}
if (!mail) {
return Resources.error(res, {data: 'Mail not found.', type: ErrorTypes.notFound});
}
res.set('X-Total-Count', total);
return Resources.success(res, mails);
}
);
});
},
return Resources.success(res, mail);
});
});
},
delete (req, res) {
withValidMailId(req, res, function (err, id) {
if (err) {
return Resources.error(res, err);
}
getAll: function (req, res) {
Resources.getValidRestParams('list', null, req, function (err, restParams) {
MailService.deleteMail(id, function (err) {
if (err) {
return Resources.error(res, err);
Logger.tag('mails', 'admin').error('Error deleting mail:', err);
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
}
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);
}
);
return Resources.success(res);
});
},
});
},
delete: function (req, res) {
withValidMailId(req, res, function (err, id) {
resetFailures (req, res) {
withValidMailId(req, res, function (err, id) {
if (err) {
return Resources.error(res, err);
}
MailService.resetFailures(id, function (err, mail) {
if (err) {
return Resources.error(res, err);
Logger.tag('mails', 'admin').error('Error resetting failure count:', err);
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
}
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);
});
return Resources.success(res, mail);
});
},
resetFailures: function (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);
});
});
}
};
});
});
}
}

Some files were not shown because too many files have changed in this diff Show more