UNPKG

@aarconada/urserver

Version:

Basic Server definitions to develope REST API with a node + express Server

857 lines (816 loc) 67 kB
/** * 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