@aarconada/urserver
Version:
Basic Server definitions to develope REST API with a node + express Server
857 lines (816 loc) • 67 kB
JavaScript
/**
* Created by ubuntu on 3/07/18.
*/
'use strict';
const server = require('./server')();
const _ = require('lodash');
const promise = require('bluebird');
const http = require('http');
const https = require('https');
const nodeForge = require('node-forge');
const moment = require('moment');
const deviceType = {
android : 'ANDROID',
ios : 'IOS'
};
const sendOnType = {
create : 'CREATE',
update : 'UPDATE',
destroy : 'DESTROY'
};
module.exports.supportedDeviceTypes = deviceType;
module.exports.supportedSendOnEvents = sendOnType;
module.exports.initialize = function() {
if (server.configuration.notification.enabled) {
var notificationSchema = {
title : {type: server.sequelize.api.STRING, allowNull: false},
body : {type: server.sequelize.api.STRING, allowNull: false},
information : {type: server.sequelize.api.STRING, allowNull: false},
sendedAt : {type: server.sequelize.api.DATE, allowNull: false, defaultValue: server.sequelize.api.NOW},
readedAt : {type: server.sequelize.api.DATE, allowNull: true},
deletedAt : {type: server.sequelize.api.DATE, allowNull: true}
};
if(server.configuration.notification.inotify.enabled) {
server.debug('Adding Push Token model...');
var tokenModel = server.sequelize.define({
modelname: 'PushToken',
schema: {
deviceId: {type: server.sequelize.api.STRING, allowNull: false},
token: {type: server.sequelize.api.STRING, allowNull: false},
deviceType: {type: server.sequelize.api.STRING, allowNull: false}
},
configuration: {
paranoid: false,
version: false,
timestamps: false
},
POST: {
single: {
enabled: false
},
all: {
enabled: false
}
},
PUT: {
single: {
enabled: false
},
all: {
enabled: false
}
},
DELETE: {
single: {
enabled: false
},
all: {
enabled: false
}
},
GET: {
single: {
enabled: false
},
all: {
enabled: false
}
}
});
server.authentication.authenticationMethodsBelongsToModel(tokenModel, {foreignKey: 'PushTokenId'});
server.debug('Push token model added');
server.endpointmanager.addEndpoint({
name: 'Set user Push Token',
description: 'Allows to add or modify the current user PushToken',
route: '/pushtoken',
method: server.utils.method.POST,
callback: function (req, res, next, allowedResponses, transaction) {
return server.authentication.getSessionUserRole(req, transaction)
.then(currentUserRole => {
if (_.isNull(currentUserRole.PushTokenId)) {
return currentUserRole.createPushToken(
{
deviceId: req.body.deviceId,
token: req.body.token,
deviceType: req.body.deviceType
},
{transaction: transaction})
.then(newPushToken => {
return {};
})
.catch(err => {
server.utils.throwError(err);
});
} else {
return server.sequelize.PushToken.destroy(
{where: {id: currentUserRole.PushTokenId}},
{transaction: transaction})
.then(destroyedToken => {
return currentUserRole.createPushToken(
{
deviceId: req.body.deviceId,
token: req.body.token,
deviceType: req.body.deviceType
},
{transaction: transaction})
.then(newPushToken => {
return {};
})
.catch(err => {
server.utils.throwError(err);
});
})
.catch(err => {
server.utils.throwError(err);
})
}
})
.catch(err => {
server.utils.throwError(allowedResponses.entity_unable_post_element, err);
});
},
parameters: [
{
name: 'deviceId',
dataType: server.utils.dataType.STRING,
parameterType: server.utils.parameterType.BODY,
required: true,
description: 'Current user device Id'
},
{
name: 'token',
dataType: server.utils.dataType.STRING,
parameterType: server.utils.parameterType.BODY,
required: true,
description: 'Current user push token'
},
{
name: 'deviceType',
dataType: server.utils.dataType.STRING,
parameterType: server.utils.parameterType.BODY,
required: true,
description: 'Current user device type (IOS or Android)'
}
],
success: {},
responses: {
entity_unable_post_element: server.defaultResponses.entity_unable_post_element,
unknown_user_type: server.defaultResponses.unknown_user_type,
unknown_user: server.defaultResponses.unknown_user
},
token: {required: true},
session: {required: true},
transactional: true
});
notificationSchema = {
title : {type: server.sequelize.api.STRING, allowNull: false},
body : {type: server.sequelize.api.STRING, allowNull: false},
information : {type: server.sequelize.api.STRING, allowNull: false},
sendedAt : {type: server.sequelize.api.DATE, allowNull: false, defaultValue: server.sequelize.api.NOW},
pushSuccess : {type: server.sequelize.api.BOOLEAN, allowNull: false, defaultValue: false},
pushFailure : {type: server.sequelize.api.BOOLEAN, allowNull: false, defaultValue: false},
pushMulticastId : {type: server.sequelize.api.DOUBLE, allowNull: true},
pushCode : {type: server.sequelize.api.STRING, allowNull: true},
pushMessage : {type: server.sequelize.api.STRING, allowNull: true},
pushResults : {type: server.sequelize.api.STRING, allowNull: true},
readedAt : {type: server.sequelize.api.DATE, allowNull: true},
deletedAt : {type: server.sequelize.api.DATE, allowNull: true}
};
}
const getSignature = function (supportTime) {
var result = null;
try {
const formattedSupportTime = new moment.utc(supportTime).format(server.configuration.notification.inotify.dateFormat);
const initialValue = server.configuration.notification.inotify.apiToken + formattedSupportTime;
const hmac = nodeForge.hmac.create();
hmac.start(server.configuration.notification.inotify.cryptoAlgorithm, server.configuration.notification.inotify.apiSecret);
hmac.update(initialValue);
result = hmac
.digest()
.toHex();
} catch (Ex) {
server.debug('iNotify Get Signature exception: ', Ex);
}
return result;
};
const sendiNotifyNotificationResult = function (res) {
var result = "";
res.setEncoding('utf8');
res.on('data', (chunk) => {
result += chunk;
});
res.on('end', () => {
const jsonResult = JSON.parse(result);
if (res.req.customCallback && jsonResult.code) {
if (jsonResult.code === 'PUSH_SERVER_SUCCESS')
res.req.customCallback(res.req.customInfo, null, jsonResult);
else
res.req.customCallback(res.req.customInfo, jsonResult, null);
} else {
res.req.customCallback(res.req.customInfo, jsonResult, null);
server.debug('RESULT:', jsonResult);
}
});
};
const sendiNotifyNotificationError = function (err) {
server.debug('Send notification error!!!');
if (!_.isUndefined(err) && !_.isUndefined(err.req) && !_.isUndefined(err.req.customCallback)) {
err.req.customCallback(err.req.customInfo, err, null);
} else {
server.debug('ERROR:', err);
}
};
const allowSendiNotifyNotifications = function () {
return server.configuration.notification.inotify.enabled &&
!_.isNull(server.configuration.notification.inotify.dateFormat) &&
!_.isNull(server.configuration.notification.inotify.apiToken) &&
!_.isNull(server.configuration.notification.inotify.protocol) &&
!_.isNull(server.configuration.notification.inotify.host) &&
!_.isNull(server.configuration.notification.inotify.port) &&
!_.isNull(server.configuration.notification.inotify.pathSendToTokens) &&
!_.isNull(server.configuration.notification.inotify.apiSecret);
};
const sendiNotifyNotification = function (title, body, information, androidTokens, iosTokens, customInfo, customCallback) {
if (allowSendiNotifyNotifications()) {
const supportTime = new moment().utc().format(server.configuration.notification.inotify.dateFormat);
const post_data = JSON.stringify({
title : title,
body : body,
information : information,
icon : server.configuration.notification.inotify.icon,
sound : server.configuration.notification.inotify.sound,
color : server.configuration.notification.inotify.color,
idApp : server.configuration.notification.inotify.idApp,
toAndroid : androidTokens,
toIos : iosTokens,
security: {
apiToken : server.configuration.notification.inotify.apiToken,
signature : getSignature(supportTime),
supportTime : supportTime
}
});
const post_options = {
protocol : server.configuration.notification.inotify.protocol,
host : server.configuration.notification.inotify.host,
port : server.configuration.notification.inotify.port,
path : server.configuration.notification.inotify.pathSendToTokens,
method : 'POST',
headers : {
'Content-Type' : 'application/json',
'Content-Length': Buffer.byteLength(post_data)
}
};
var post_req = null;
if (server.configuration.notification.inotify.protocol.toUpperCase() === "HTTP:") {
post_req = http.request(post_options, sendiNotifyNotificationResult);
} else if (server.configuration.notification.inotify.protocol.toUpperCase() === "HTTPS:") {
post_req = https.request(post_options, sendiNotifyNotificationResult);
} else {
return false;
}
post_req.customInfo = customInfo;
post_req.customCallback = customCallback;
post_req.on('error', sendiNotifyNotificationError);
post_req.write(post_data);
post_req.end();
return true;
}
};
server.debug('Adding Notification model...');
var postSingleConfiguration = {
enabled : server.configuration.notification.custom.enabled
};
if(server.configuration.notification.custom.enabled) {
server.debug('Generating send notification callback');
const findNotificationCallback = function(req) {
if(_.isUndefined(server.configuration.notification.custom.definitions) || _.isNull(server.configuration.notification.custom.definitions) || !_.isArray(server.configuration.notification.custom.definitions) || server.configuration.notification.custom.definitions.length === 0) return null;
return server.configuration.notification.custom.definitions.filter(currentNotification => currentNotification.type === req.body.type);
};
const isValidSenderCallback = function (req, notification) {
server.debug('Begin is valid sender');
if(_.isUndefined(notification.senders) || _.isNull(notification.senders) ||!_.isArray(notification.senders) || notification.senders.length === 0) return false;
var result = false;
for(var senderIndex = 0; senderIndex < notification.senders.length; senderIndex ++) {
var currentSender = notification.senders[senderIndex];
var currentRole = null;
if(!_.isUndefined(currentSender.roleName) && !_.isNull(currentSender.roleName) && !_.isEmpty(currentSender.roleName)) {
currentRole = server.roles.getRoleByName(currentSender.roleName);
} else if(!_.isUndefined(currentSender.roleId) && !_.isNull(currentSender.roleId) && !_.isEmpty(currentSender.roleId)) {
currentRole = server.roles.getRoleById(currentSender.roleId);
}
if(!_.isUndefined(currentRole) && !_.isNull(currentRole)) {
result = result || (currentRole.id === req.currentSession.role)|| (currentRole.name === req.currentSession.role)|| (currentRole === req.currentSession.role);
}
}
server.debug('End is valid sender');
return result;
};
const findReceiversCallback = function(req, notification) {
return new promise((resolve, reject) => {
server.debug('Begin find receiver');
if (_.isUndefined(notification.receivers) || _.isNull(notification.receivers) || !_.isArray(notification.receivers) || notification.receivers.length === 0) resolve({receivers: null, notification: notification});
var requestInfo = _.isUndefined(req.body.info) || _.isNull(req.body.info) ? null : JSON.parse(req.body.info);
var results = [];
var rolesObtained = 0;
for(var currentIndex = 0; currentIndex < notification.receivers.length; currentIndex++) {
var currentReceiver = notification.receivers[currentIndex];
var currentRole = null;
if (!_.isUndefined(currentReceiver.roleName) && !_.isNull(currentReceiver.roleName) && !_.isEmpty(currentReceiver.roleName)) {
currentRole = server.roles.getRoleByName(currentReceiver.roleName);
} else if (!_.isUndefined(currentReceiver.roleId) && !_.isNull(currentReceiver.roleId) && !_.isEmpty(currentReceiver.roleId)) {
currentRole = server.roles.getRoleById(currentReceiver.roleId);
}
if (!_.isUndefined(currentRole) && !_.isNull(currentRole)) {
var currentWhere = {};
if (!_.isUndefined(currentReceiver.filters) && !_.isNull(currentReceiver.filters)) {
var filterKeys = Object.keys(currentReceiver.filters);
for(var filterIndex = 0; filterIndex < filterKeys.length; filterIndex++) {
var currentFilterKey = filterKeys[filterIndex];
var currentFilterValue = currentReceiver.filters[currentFilterKey];
if(!_.isNull(currentFilterValue) && currentFilterValue.toString().toUpperCase() === 'INFO') {
if(requestInfo.hasOwnProperty(currentFilterKey)) {
currentWhere[currentFilterKey] = requestInfo[currentFilterKey];
} else {
currentWhere = null;
break;
}
} else {
currentWhere[currentFilterKey] = currentFilterValue;
}
}
}
server.debug(currentWhere);
if(!_.isNull(currentWhere)) {
currentRole.model.findAll(
{
where: {[server.sequelize.api.Op.and]: currentWhere},
})
.then(currentResults => {
for (var currentResultIndex = 0; currentResultIndex < currentResults.length; currentResultIndex++) {
var currentResult = currentResults[currentResultIndex];
results.push(currentResult);
}
rolesObtained++;
server.debug(rolesObtained);
if (rolesObtained === notification.receivers.length) {
resolve({receivers: results, notification: notification});
}
})
.catch(err => {
server.debug(err);
reject(err);
});
} else {
resolve({receivers: [], notification: notification});
}
}
}
});
};
const composeMessageCallback = function(req, notification, receiver) {
if(_.isUndefined(notification.title) || _.isNull(notification.title)) return null;
if(_.isUndefined(notification.body) || _.isNull(notification.body)) return null;
if(_.isUndefined(notification.information) || _.isNull(notification.information)) return null;
return {
title : notification.title,
body : notification.body,
information : notification.information
};
};
const handleSendNotification = function(req, transaction) {
return new promise((resolve, reject) => {
var notifications = _.isNull(server.configuration.notification.custom.findNotificationCallback) ? findNotificationCallback(req) : server.configuration.notification.custom.findNotificationCallback(req);
if (_.isUndefined(notifications) || _.isNull(notifications) || !_.isArray(notifications) || notifications.length === 0) reject(server.defaultResponses.notification_unknow_notification_type);
var totalNotificationsToSend = 0;
var totalNotificationsSended = 0;
for(var notificationIndex = 0; notificationIndex < notifications.length; notificationIndex++) {
var currentNotification = notifications[notificationIndex];
var validSender = _.isUndefined(currentNotification.isValidSenderCallback) || _.isNull(currentNotification.isValidSenderCallback) ? isValidSenderCallback(req, currentNotification) : currentNotification.isValidSenderCallback(req, currentNotification);
if (validSender) {
var receiversPromise = _.isUndefined(currentNotification.findReceiversCallback) || _.isNull(currentNotification.findReceiversCallback) ? findReceiversCallback(req, currentNotification) : currentNotification.findReceiversCallback(req, currentNotification);
receiversPromise.then(results => {
var receivers = results.receivers;
var notificationToSend = results.notification;
if (_.isUndefined(receivers) || _.isNull(receivers) || !_.isArray(receivers) || receivers.length === 0) reject(server.defaultResponses.notification_missing_receivers);
totalNotificationsToSend += receivers.length;
for(var receiverIndex = 0; receiverIndex < receivers.length; receiverIndex++) {
var currentReceiver = receivers[receiverIndex];
var composedMessage = _.isUndefined(notificationToSend.composeMessageCallback) || _.isNull(notificationToSend.composeMessageCallback) ? composeMessageCallback(req, notificationToSend, currentReceiver) : notificationToSend.composeMessageCallback(req, notificationToSend, currentReceiver);
if (!_.isUndefined(composedMessage) && !_.isNull(composedMessage)) {
module.exports.sendNotificationToUser(composedMessage.title, composedMessage.body, composedMessage.information, currentReceiver, currentNotification, null, transaction)
.then(results => {
if(!_.isUndefined(notificationToSend.onSingleNotificationSended) && !_.isNull(notificationToSend.onSingleNotificationSended) && _.isFunction(notificationToSend.onSingleNotificationSended)) notificationToSend.onSingleNotificationSended(req, transaction, currentReceiver, notificationToSend, results);
totalNotificationsSended++;
if(totalNotificationsToSend === totalNotificationsSended) {
server.debug('Finishing send...');
if (totalNotificationsSended > 0) {
if(!_.isUndefined(notificationToSend.onAllNotificationsSended) && !_.isNull(notificationToSend.onAllNotificationsSended) && _.isFunction(notificationToSend.onAllNotificationsSended)) notificationToSend.onAllNotificationsSended(req, transaction, {total: totalNotificationsSended});
resolve({total: totalNotificationsSended});
} else {
reject(server.defaultResponses.notification_no_notifications_to_send)
}
}
})
.catch(err => {
reject(err);
})
} else {
reject(server.defaultResponses.notification_unable_send);
}
}
})
.catch(err => {
reject(err)
})
} else {
reject(server.defaultResponses.unauthorized);
}
}
});
};
postSingleConfiguration.name = "Send notification";
postSingleConfiguration.description = "This endpoint allows send custom notifications";
postSingleConfiguration.callback = function (req, res, next, allowedResponses, transaction) {
return handleSendNotification(req, transaction)
.then(result => {
return result;
})
.catch(err => {
server.utils.throwError(server.defaultResponses.notification_unable_send, err);
})
};
postSingleConfiguration.parameters = [
{
name: 'type',
dataType: server.utils.dataType.STRING,
parameterType: server.utils.parameterType.BODY,
required: true,
description: 'The id of the notification to send'
},
{
name: 'info',
dataType: server.utils.dataType.JSON,
parameterType: server.utils.parameterType.BODY,
required: true,
description: 'Notification info to find receivers, compose message...'
}
];
}
var notificationModel = server.sequelize.define({
modelname: 'Notification',
schema: notificationSchema,
configuration: {
paranoid : false,
version : false,
timestamps : false
},
POST: {
single: postSingleConfiguration,
all: {
enabled: false
}
},
PUT: {
single: {
name : 'Read notification',
description : 'This endpoint mark as readed/unreaded or delete/undelete the notification with de received :id',
enabled : true,
callback : function (req, res, next, allowedResponses, transaction) {
server.debug('Mark as readed Notification with id', req.params.id);
var findWhere = [
{id: req.params.id}
];
var filterObject = server.authentication.getSessionUserRoleFilter(req);
if(!_.isNull(filterObject)) {
findWhere.push(filterObject);
} else {
server.utils.throwError(allowedResponses.unknown_user);
}
return server.sequelize.Notification.findOne({
where: {[server.sequelize.api.Op.and]: findWhere},
include: {all: true},
transaction: transaction
}).then(foundedElement => {
if(foundedElement === null) server.utils.throwError(allowedResponses.entity_element_not_found);
var assignations = {};
server.debug('Readed: ', req.body.readed);
server.debug('Deleted: ', req.body.deleted);
var hasAssignations = false;
if(!_.isUndefined(req.body.readed)) {
if(server.utils.parseBoolean(req.body.readed)) {
assignations.readedAt = new Date();
} else {
assignations.readedAt = null;
}
hasAssignations = true;
}
if(!_.isUndefined(req.body.deleted)) {
if(server.utils.parseBoolean(req.body.deleted)) {
assignations['deletedAt'] = new Date();
} else {
assignations['deletedAt'] = null;
}
hasAssignations = true;
}
if(hasAssignations) {
return foundedElement.update(
assignations,
{
transaction: transaction
})
.then(updatedElement => {
server.socket.Emit('NOTIFICATION' + server.socket.Events.EntityUpdated, updatedElement);
return {
id: updatedElement.id
};
})
.catch(err => {
server.debug(err);
server.utils.throwError(allowedResponses.entity_unable_update_element, err);
});
} else {
server.utils.throwError(allowedResponses.missing_parameter);
}
}).catch(err => {
server.debug(err);
server.utils.throwError(allowedResponses.entity_unable_update_element, err);
});
},
parameters : [
{
name: 'id',
dataType: server.utils.dataType.INTEGER,
parameterType: server.utils.parameterType.PARAM,
required: true,
description: 'The id of the readed Notification'
},
{
name: 'readed',
dataType: server.utils.dataType.BOOLEAN,
parameterType: server.utils.parameterType.BODY,
required: false,
description: 'Indicates if the notification is readed or not'
},
{
name: 'deleted',
dataType: server.utils.dataType.BOOLEAN,
parameterType: server.utils.parameterType.BODY,
required: false,
description: 'Indicates if the notification is readed or not'
}
]
},
all: {
enabled: false
}
},
DELETE: {
single : {enabled: false,},
all : {enabled: false}
},
GET: {
single : {enabled: false},
all : {
enabled: true,
callback: function (req, res, next, allowedResponses) {
var attributes = null;
var include = null;
var limit = null;
var offset = null;
var order = [];
var findWhere = [];
var filterObject = server.authentication.getSessionUserRoleFilter(req);
if(!_.isNull(filterObject)) {
findWhere.push(filterObject);
} else {
server.utils.throwError(allowedResponses.unknown_user);
}
Object.keys(req.query).forEach(currentParameter => {
if(currentParameter === 'fields') {
attributes = req.query.fields.split(',');
include = [];
} else if(currentParameter === 'limit') {
limit = +req.query.limit;
}else if(currentParameter === 'offset') {
offset = +req.query.offset;
}else if(currentParameter === 'sort') {
req.query.sort.split(',').forEach(currentSortValue => {
currentSortValue = currentSortValue.trim();
var sortType = 'ASC';
var fieldName = '';
if (currentSortValue[0] === '-') {
sortType = 'DESC';
fieldName = currentSortValue.substring(1);
} else if (currentSortValue[0] === '+') {
fieldName = currentSortValue.substring(1);
} else {
fieldName = currentSortValue;
}
order.push([fieldName, sortType]);
});
} else if(currentParameter === 'filter') {
findWhere.push(server.sequelize.api.literal('(' + req.query.filter + ')'));
}
});
server.debug('Getting list of Notifications');
return server.sequelize.Notification.findAll({
attributes: attributes,
include: include,
where: {[server.sequelize.api.Op.and]: findWhere},
limit: limit,
offset: offset,
order: order
}).then(elements => {
return elements;
}).catch(err => {
server.debug(err);
server.utils.throwError(allowedResponses.entity_unable_get_list, err);
});
}
}
}
});
server.authentication.modelBelongsToManyAuthenticationMethods(notificationModel);
server.debug('Notification model added');
const registerNotification = function (customInfo, error, result) {
if (_.isNull(error)) {
server.logger.log('iNotify', result);
if (!_.isUndefined(customInfo) && !_.isNull(customInfo)) {
if (!_.isUndefined(customInfo.notificationId)) {
const notificationValues = {
pushCode: result.code ? result.code : 'GENERIC_ERROR',
pushMessage: result.message ? result.message : result
};
const currentResponse = result.response[0];
if (!_.isUndefined(currentResponse)) {
notificationValues.pushMulticastId = currentResponse.multicast_id;
notificationValues.pushSuccess = currentResponse.success === result.numberTokensSent;
notificationValues.pushFailure = !notificationValues.pushSuccess;
notificationValues.pushResults = JSON.stringify(currentResponse.results);
}
server.sequelize.Notification.update(
notificationValues,
{
where: {id: customInfo.notificationId}
})
.then(notificationUpdated => {
server.socket.Emit('NOTIFICATION' + server.socket.Events.EntityUpdated, notificationUpdated);
if (notificationValues.pushSuccess && _.isFunction(customInfo.resolve)) customInfo.resolve(result);
if (notificationValues.pushFailure && _.isFunction(customInfo.reject)) customInfo.reject(server.defaultResponses.notification_unable_send);
})
.catch(err => {
if (_.isFunction(customInfo.reject)) customInfo.reject(server.defaultResponses.notification_unable_send);
});
} else if (_.isFunction(customInfo.resolve)) customInfo.resolve(result);
}
} else {
server.logger.log('iNotify', error);
server.debug(error);
if (!_.isUndefined(customInfo) && !_.isNull(customInfo)) {
if (!_.isUndefined(customInfo.notificationId)) {
server.debug('Updating notification', customInfo.notificationId);
server.sequelize.Notification.update(
{
pushFailure: true,
pushCode: error.code ? error.code : 'GENERIC_ERROR',
pushMessage: error.message ? error.message : error
},
{
where: {id: customInfo.notificationId}
})
.then(notificationUpdated => {
server.socket.Emit('NOTIFICATION' + server.socket.Events.EntityUpdated, notificationUpdated);
if (_.isFunction(customInfo.reject)) customInfo.reject(server.defaultResponses.notification_unable_send);
})
.catch(err => {
if (_.isFunction(customInfo.reject)) customInfo.reject(server.defaultResponses.notification_unable_send);
});
} else if (_.isFunction(customInfo.reject)) customInfo.reject(server.defaultResponses.notification_unable_send);
}
}
};
module.exports.sendNotificationToCurrentUser = function (title, body, information, req, notification, instance, transaction) {
return new promise((resolve, reject) => {
server.authentication.getSessionUserRole(req, transaction)
.then(userRole => {
module.exports.sendNotificationToUserRole(title, body, information, userRole, notification, instance, transaction, resolve, reject);
})
.catch(err => {
reject(server.defaultResponses.notification_unable_send);
});
});
};
module.exports.sendNotificationToUser = function (title, body, information, user, notification, instance, transaction) {
return new promise((resolve, reject) => {
server.authentication.getUserRole(user, transaction)
.then(userRole => {
module.exports.sendNotificationToUserRole(title, body, information, userRole, notification, instance, transaction, resolve, reject);
})
.catch(err => {
reject(server.defaultResponses.notification_unable_send);
});
});
};
module.exports.sendNotificationToUserRole = function (title, body, information, userRole, notification, instance, transaction, resolve, reject) {
userRole.createNotification(
{
title: title,
body: body,
information: information
})
.then(createdNotification => {
server.socket.Emit('NOTIFICATION' + server.socket.Events.EntityCreated, createdNotification);
if (!_.isUndefined(notification.email) && notification.email === true && !_.isUndefined(userRole.email) && !_.isNull(userRole.email) && !_.isEmpty(userRole.email)) {
if (_.isUndefined(notification.emailTemplate) || _.isNull(notification.emailTemplate) || _.isEmpty(notification.emailTemplate)) {
server.email.sendHtmlEmail(userRole.email, title, body);
} else {
var template = server.fileSystem.readFile(server.configuration.email.templatePath, notification.emailTemplate);
const templateAttachments = server.fileSystem.getFilesAttachments(server.configuration.email.templatePath, notification.emailTemplate);
if (!_.isUndefined(notification.emailReplacements) && !_.isNull(notification.emailReplacements) && _.isObject(notification.emailReplacements)) {
Object.keys(notification.emailReplacements).forEach(currentReplacement => {
var replaceValue = notification.emailReplacements[currentReplacement];
if (replaceValue.toUpperCase().startsWith('INSTANCE.')) {
const instanceField = replaceValue.substring(9);
const instanceFieldValue = instance[instanceField];
if (!_.isUndefined(instanceFieldValue) && !_.isNull(instanceFieldValue)) {
template = template.split(currentReplacement).join(instanceFieldValue);
} else {
template = template.split(currentReplacement).join('');
}
} else if (replaceValue.toUpperCase().startsWith('USERROLE.')) {
const userRoleField = replaceValue.substring(9);
const userRoleFieldValue = userRole[userRoleField];
if (!_.isUndefined(userRoleFieldValue) && !_.isNull(userRoleFieldValue)) {
template = template.split(currentReplacement).join(userRoleFieldValue);
} else {
template = template.split(currentReplacement).join('');
}
} else {
template = template.split(currentReplacement).join(replaceValue);
}
})
}
server.email.sendHtmlEmailWithAttachments(userRole.email, title, template, templateAttachments);
}
}
if (
_.isUndefined(server.configuration.notification.inotify.enabled) || _.isNull(server.configuration.notification.inotify.enabled) || server.configuration.notification.inotify.enabled === false ||
_.isUndefined(notification.iNotify) || _.isNull(notification.iNotify) || notification.iNotify === false ||
_.isNull(userRole.PushTokenId)
) {
resolve(createdNotification);
} else {
return userRole.getPushToken({transaction: transaction})
.then(userPushToken => {
if (_.isUndefined(userPushToken) || _.isNull(userPushToken)) {
resolve(createdNotification);
} else {
const customInfo = {
notificationId: createdNotification.id,
transaction: transaction,
resolve: resolve,
reject: reject
};
if (_.isEqual(userPushToken.deviceType.toUpperCase(), deviceType.android)) {
if(!sendiNotifyNotification(title, body, information, [userPushToken.token], [], customInfo, registerNotification)) {
reject(server.defaultResponses.notification_unable_send);
}
} else if (_.isEqual(userPushToken.deviceType.toUpperCase(), deviceType.ios)) {
if(!sendiNotifyNotification(title, body, information, [], [userPushToken.token], customInfo, registerNotification)) {
reject(server.defaultResponses.notification_unable_send);
}
} else {
reject(server.defaultResponses.notification_unknow_device_type);
}
}
})
.catch(err => {
server.debug(err);
reject(server.defaultResponses.notification_unable_send);
})
}
})
.catch(err => {
reject(server.defaultResponses.notification_unable_create_notification);
});
};
}
};
module.exports.addCustomNotification = function(newNotification) {
if(
_.isUndefined(newNotification.name) || _.isNull(newNotification.name) || _.isEmpty(newNotification.name) ||
_.isUndefined(newNotification.description) || _.isNull(newNotification.description) || _.isEmpty(newNotification.description) ||
_.isUndefined(newNotification.type) || _.isNull(newNotification.type) || _.isEmpty(newNotification.type) ||
_.isUndefined(newNotification.title) || _.isNull(newNotification.title) || _.isEmpty(newNotification.title) ||
_.isUndefined(newNotification.body) || _.isNull(newNotification.body) || _.isEmpty(newNotification.body) ||
_.isUndefined(newNotification.information) || _.isNull(newNotification.information) || _.isEmpty(newNotification.information) ||
_.isUndefined(newNotification.senders) || _.isNull(newNotification.senders) || !_.isArray(newNotification.senders) || newNotification.senders.length === 0 ||
_.isUndefined(newNotification.receivers) || _.isNull(newNotification.receivers) || !_.isArray(newNotification.receivers) || newNotification.receivers.length === 0
) return false;
if(_.isUndefined(server.configuration.notification.custom.definitions) || _.isNull(server.configuration.notification.custom.definitions)) server.configuration.notification.custom.definitions = [];
server.configuration.notification.custom.definitions.push(newNotification);
return true;
};
module.exports.addModelNotification = function(newNotification) {
if(
_.isUndefined(newNotification.name) || _.isNull(newNotification.name) || _.isEmpty(newNotif