Функция валидации списка E-mail адресов в общие объекты моделей валидации, перенос функции отправки E-mail в utils.js (соответственно перенос схем валидации), включение валидации списка E-mail адресов в схеме Service
This commit is contained in:
parent
1233efb6f5
commit
d6beebabc5
@ -10,10 +10,9 @@
|
||||
const _ = require("lodash"); //Работа с массивами и коллекциями
|
||||
const rqp = require("request-promise"); //Работа с HTTP/HTTPS запросами
|
||||
const EventEmitter = require("events"); //Обработчик пользовательских событий
|
||||
const nodemailer = require("nodemailer"); //Отправка E-Mail сообщений
|
||||
const { ServerError } = require("./server_errors"); //Типовая ошибка
|
||||
const { SERR_SERVICE_UNAVAILABLE, SERR_MAIL_FAILED, SERR_OBJECT_BAD_INTERFACE } = require("./constants"); //Общесистемные константы
|
||||
const { makeErrorText, validateObject } = require("./utils"); //Вспомогательные функции
|
||||
const { SERR_SERVICE_UNAVAILABLE, SERR_OBJECT_BAD_INTERFACE } = require("./constants"); //Общесистемные константы
|
||||
const { makeErrorText, validateObject, sendMail } = require("./utils"); //Вспомогательные функции
|
||||
const prmsServiceAvailableControllerSchema = require("../models/prms_service_available_controller"); //Схемы валидации параметров функций класса
|
||||
const objServiceSchema = require("../models/obj_service"); //Схемы валидации сервисов
|
||||
|
||||
@ -79,56 +78,6 @@ class ServiceAvailableController extends EventEmitter {
|
||||
//Оповестим подписчиков об останове
|
||||
this.emit(SEVT_SERVICE_AVAILABLE_CONTROLLER_STOPPED);
|
||||
}
|
||||
//Отправка E-Mail уведомления о недоступности сервиса
|
||||
sendUnAvailableMail(prms) {
|
||||
return new Promise((resolve, reject) => {
|
||||
//Проверяем структуру переданного объекта для старта
|
||||
let sCheckResult = validateObject(
|
||||
prms,
|
||||
prmsServiceAvailableControllerSchema.sendUnAvailableMail,
|
||||
"Параметры функции отправки E-Mail уведомления о недоступности удалённого сервиса"
|
||||
);
|
||||
//Если структура объекта в норме
|
||||
if (!sCheckResult) {
|
||||
//Параметры подключения к SMTP-серверу
|
||||
let transporter = nodemailer.createTransport({
|
||||
host: this.mail.sHost,
|
||||
port: this.mail.nPort,
|
||||
secure: this.mail.nPort == 465,
|
||||
auth: {
|
||||
user: this.mail.sUser,
|
||||
pass: this.mail.sPass
|
||||
}
|
||||
});
|
||||
//Параметры отправляемого сообщения
|
||||
let mailOptions = {
|
||||
from: this.mail.sFrom,
|
||||
to: prms.sTo,
|
||||
subject: prms.sSubject,
|
||||
text: prms.sMessage
|
||||
};
|
||||
//Отправляем сообщение
|
||||
transporter.sendMail(mailOptions, (error, info) => {
|
||||
if (error) {
|
||||
reject(new ServerError(SERR_MAIL_FAILED, `${error.code}: ${error.response}`));
|
||||
} else {
|
||||
if (info.rejected && Array.isArray(info.rejected) && info.rejected.length > 0) {
|
||||
reject(
|
||||
new ServerError(
|
||||
SERR_MAIL_FAILED,
|
||||
`Сообщение не доствлено адресатам: ${info.rejected.join(", ")}`
|
||||
)
|
||||
);
|
||||
} else {
|
||||
resolve(info);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
reject(new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult));
|
||||
}
|
||||
});
|
||||
}
|
||||
//Перезапуск опроса списка сервисов
|
||||
async restartDetectingLoop() {
|
||||
//Включаем опрос сервисов только если установлен флаг работы
|
||||
@ -197,7 +146,8 @@ class ServiceAvailableController extends EventEmitter {
|
||||
}`;
|
||||
await this.logger.error(sMessage, { nServiceId: this.services[i].nId });
|
||||
try {
|
||||
await this.sendUnAvailableMail({
|
||||
await sendMail({
|
||||
mail: this.mail,
|
||||
sTo: this.services[i].sUnavlblNtfMail,
|
||||
sSubject,
|
||||
sMessage
|
||||
|
@ -9,13 +9,17 @@
|
||||
|
||||
const _ = require("lodash"); //Работа с массивами и объектами
|
||||
const Schema = require("validate"); //Схемы валидации
|
||||
const nodemailer = require("nodemailer"); //Отправка E-Mail сообщений
|
||||
const {
|
||||
SERR_UNEXPECTED,
|
||||
SMODULES_PATH_MODULES,
|
||||
SERR_OBJECT_BAD_INTERFACE,
|
||||
SERR_MODULES_NO_MODULE_SPECIFIED,
|
||||
SERR_MODULES_BAD_INTERFACE
|
||||
SERR_MODULES_BAD_INTERFACE,
|
||||
SERR_MAIL_FAILED
|
||||
} = require("./constants"); //Глобавльные константы системы
|
||||
const { ServerError } = require("./server_errors"); //Ошибка сервера
|
||||
const prmsUtilsSchema = require("../models/prms_utils"); //Схемы валидации параметров функций
|
||||
|
||||
//------------
|
||||
// Тело модуля
|
||||
@ -25,12 +29,17 @@ const { ServerError } = require("./server_errors"); //Ошибка сервер
|
||||
const validateObject = (obj, schema, sObjName) => {
|
||||
//Объявим результат
|
||||
let sRes = "";
|
||||
//Если пришла верная схема
|
||||
if (schema instanceof Schema) {
|
||||
//И есть что проверять
|
||||
if (obj) {
|
||||
//Сделаем это
|
||||
const objTmp = _.cloneDeep(obj);
|
||||
const errors = schema.validate(objTmp, { strip: false });
|
||||
//Если есть ошибки
|
||||
if (errors && Array.isArray(errors)) {
|
||||
if (errors.length > 0) {
|
||||
//Сформируем из них сообщение об ошибке валидации
|
||||
let a = errors.map(e => {
|
||||
return e.message;
|
||||
});
|
||||
@ -41,12 +50,15 @@ const validateObject = (obj, schema, sObjName) => {
|
||||
_.uniq(a).join("; ");
|
||||
}
|
||||
} else {
|
||||
//Валидатор вернул не то, что мы ожидали
|
||||
sRes = "Неожиданный ответ валидатора";
|
||||
}
|
||||
} else {
|
||||
//Нам не передали объект на проверку
|
||||
sRes = "Объект" + (sObjName ? " '" + sObjName + "' " : " ") + "не указан";
|
||||
}
|
||||
} else {
|
||||
//Пришла не схема валидации а непонятно что
|
||||
sRes = "Ошибочный формат схемы валидации";
|
||||
}
|
||||
//Вернем результат
|
||||
@ -55,50 +67,70 @@ const validateObject = (obj, schema, sObjName) => {
|
||||
|
||||
//Формирование полного пути к подключаемому модулю
|
||||
const makeModuleFullPath = sModuleName => {
|
||||
//Если имя модуля передано
|
||||
if (sModuleName) {
|
||||
//Объединим его с шаблоном пути до библиотеки модулей
|
||||
return SMODULES_PATH_MODULES + "/" + sModuleName;
|
||||
} else {
|
||||
//Нет имени модуля - нет полного пути
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
//Формирование текста ошибки
|
||||
const makeErrorText = e => {
|
||||
//Сообщение об ошибке по умолчанию
|
||||
let sErr = `${SERR_UNEXPECTED}: ${e.message}`;
|
||||
//Если это наше внутреннее сообщение, с кодом, то сделаем ошибку более информативной
|
||||
if (e instanceof ServerError) sErr = `${e.sCode}: ${e.sMessage}`;
|
||||
//Вернем ответ
|
||||
return sErr;
|
||||
};
|
||||
|
||||
//Считывание наименования модуля-обработчика сервера приложений (ожидаемый формат - <МОДУЛЬ>/<ФУНКЦИЯ>)
|
||||
const getAppSrvModuleName = sAppSrv => {
|
||||
//Если есть что разбирать
|
||||
if (sAppSrv) {
|
||||
//И если это строка
|
||||
if (sAppSrv instanceof String || typeof sAppSrv === "string") {
|
||||
//Проверим наличие разделителя между именем модуля и функции
|
||||
if (sAppSrv.indexOf("/") === -1) {
|
||||
//Нет разделителя - нечего вернуть
|
||||
return null;
|
||||
} else {
|
||||
//Вернём всё, что левее разделителя
|
||||
return sAppSrv.substring(0, sAppSrv.indexOf("/"));
|
||||
}
|
||||
} else {
|
||||
//Пришла не строка
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
//Ничего не пришло
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
//Считывание наименования функции модуля-обработчика сервера приложений (ожидаемый формат - <МОДУЛЬ>/<ФУНКЦИЯ>)
|
||||
const getAppSrvFunctionName = sAppSrv => {
|
||||
//Если есть что разбирать
|
||||
if (sAppSrv) {
|
||||
//И если это строка
|
||||
if (sAppSrv instanceof String || typeof sAppSrv === "string") {
|
||||
//Проверим наличие разделителя между именем модуля и функции
|
||||
if (sAppSrv.indexOf("/") === -1) {
|
||||
//Нет разделителя - нечего вернуть
|
||||
return null;
|
||||
} else {
|
||||
//Вернём всё, что правее разделителя
|
||||
return sAppSrv.substring(sAppSrv.indexOf("/") + 1, sAppSrv.length);
|
||||
}
|
||||
} else {
|
||||
//Пришла не строка
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
//Ничего не пришло
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@ -139,6 +171,57 @@ const getAppSrvFunction = sAppSrv => {
|
||||
}
|
||||
};
|
||||
|
||||
//Отправка E-Mail уведомления
|
||||
const sendMail = prms => {
|
||||
return new Promise((resolve, reject) => {
|
||||
//Проверяем структуру переданного объекта для старта
|
||||
let sCheckResult = validateObject(
|
||||
prms,
|
||||
prmsUtilsSchema.sendMail,
|
||||
"Параметры функции отправки E-Mail уведомления"
|
||||
);
|
||||
//Если структура объекта в норме
|
||||
if (!sCheckResult) {
|
||||
//Параметры подключения к SMTP-серверу
|
||||
let transporter = nodemailer.createTransport({
|
||||
host: prms.mail.sHost,
|
||||
port: prms.mail.nPort,
|
||||
secure: prms.mail.nPort == 465,
|
||||
auth: {
|
||||
user: prms.mail.sUser,
|
||||
pass: prms.mail.sPass
|
||||
}
|
||||
});
|
||||
//Параметры отправляемого сообщения
|
||||
let mailOptions = {
|
||||
from: prms.mail.sFrom,
|
||||
to: prms.sTo,
|
||||
subject: prms.sSubject,
|
||||
text: prms.sMessage
|
||||
};
|
||||
//Отправляем сообщение
|
||||
transporter.sendMail(mailOptions, (error, info) => {
|
||||
if (error) {
|
||||
reject(new ServerError(SERR_MAIL_FAILED, `${error.code}: ${error.response}`));
|
||||
} else {
|
||||
if (info.rejected && Array.isArray(info.rejected) && info.rejected.length > 0) {
|
||||
reject(
|
||||
new ServerError(
|
||||
SERR_MAIL_FAILED,
|
||||
`Сообщение не доствлено адресатам: ${info.rejected.join(", ")}`
|
||||
)
|
||||
);
|
||||
} else {
|
||||
resolve(info);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
reject(new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//-----------------
|
||||
// Интерфейс модуля
|
||||
//-----------------
|
||||
@ -149,3 +232,4 @@ exports.makeErrorText = makeErrorText;
|
||||
exports.getAppSrvModuleName = getAppSrvModuleName;
|
||||
exports.getAppSrvFunctionName = getAppSrvFunctionName;
|
||||
exports.getAppSrvFunction = getAppSrvFunction;
|
||||
exports.sendMail = sendMail;
|
||||
|
34
models/common.js
Normal file
34
models/common.js
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
Сервис интеграции ПП Парус 8 с WEB API
|
||||
Модели данных: общие функции валидации, константы, модели
|
||||
*/
|
||||
|
||||
//------------
|
||||
// Тело модуля
|
||||
//------------
|
||||
|
||||
//Валидация списка адресов E-Mail
|
||||
const validateMailList = sMailList => {
|
||||
//Если есть что валидировать
|
||||
if (sMailList) {
|
||||
//Объявим разделитель списка адресов
|
||||
let sSpr = ",";
|
||||
//Регулярное выражение для контроля адреса E-Mail
|
||||
let sMailRegExp = /^(([A-Za-z0-9_-]+\.)*[A-Za-z0-9_-]+@[a-z0-9_-]+(\.[a-z0-9_-]+)*\.[a-z]+)/;
|
||||
//Развалим строку с разделителями на массив адресов
|
||||
let addrs = sMailList.split(sSpr);
|
||||
//Обходим массив адресов
|
||||
for (i = 0; i < addrs.length; i++) {
|
||||
//Проверяем адрес на соответствие регулярному выражению
|
||||
if (!sMailRegExp.test(addrs[i])) return false;
|
||||
}
|
||||
}
|
||||
//Если мы здесь - валидация прошла успешно
|
||||
return true;
|
||||
};
|
||||
|
||||
//-----------------
|
||||
// Интерфейс модуля
|
||||
//-----------------
|
||||
|
||||
exports.validateMailList = validateMailList;
|
@ -9,6 +9,7 @@
|
||||
|
||||
const Schema = require("validate"); //Схемы валидации
|
||||
const { defServiceFunctions } = require("./obj_service_functions"); //Схема валидации списка функций сервиса
|
||||
const { validateMailList } = require("./common"); //Общие объекты валидации моделей данных
|
||||
|
||||
//----------
|
||||
// Константы
|
||||
@ -26,6 +27,15 @@ const NUNAVLBL_NTF_SIGN_YES = 1; //Оповещать о простое
|
||||
const SUNAVLBL_NTF_SIGN_NO = "UNAVLBL_NTF_NO"; //Не оповещать о простое (строковый код)
|
||||
const SUNAVLBL_NTF_SIGN_YES = "UNAVLBL_NTF_YES"; //Оповещать о простое (строковый код)
|
||||
|
||||
//-------------
|
||||
// Тело модуля
|
||||
//-------------
|
||||
|
||||
//Валидация списка адресов E-Mail для оповещения о простое внешнего сервиса
|
||||
const validateUnavlblNtfMail = val => {
|
||||
return validateMailList(val);
|
||||
};
|
||||
|
||||
//------------------
|
||||
// Интерфейс модуля
|
||||
//------------------
|
||||
@ -151,10 +161,13 @@ exports.Service = new Schema({
|
||||
sUnavlblNtfMail: {
|
||||
type: String,
|
||||
required: false,
|
||||
use: { validateUnavlblNtfMail },
|
||||
message: {
|
||||
type:
|
||||
"Список адресов E-Mail для оповещения о простое внешнего сервиса (sUnavlblNtfMail) имеет некорректный тип данных (ожидалось - String)",
|
||||
required: "Не указан список адресов E-Mail для оповещения о простое внешнего сервиса (sUnavlblNtfMail)"
|
||||
required: "Не указан список адресов E-Mail для оповещения о простое внешнего сервиса (sUnavlblNtfMail)",
|
||||
validateUnavlblNtfMail:
|
||||
"Неверный формат списка адресов E-Mail для оповещения о простое внешнего сервиса (sUnavlblNtfMail), для указания нескольких адресов следует использовать запятую в качестве разделителя (без пробелов)"
|
||||
}
|
||||
},
|
||||
//Список функций сервиса
|
||||
|
@ -38,38 +38,6 @@ exports.ServiceAvailableController = new Schema({
|
||||
}
|
||||
});
|
||||
|
||||
//Схема валидации параметров функции отправки E-Mail уведомления о недоступности сервиса
|
||||
exports.sendUnAvailableMail = new Schema({
|
||||
//Список адресов E-Mail для отправки уведомления
|
||||
sTo: {
|
||||
type: String,
|
||||
required: true,
|
||||
message: {
|
||||
type: path =>
|
||||
`Список адресов E-Mail для отправки уведомления (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||
required: path => `Не указан cписок адресов E-Mail для отправки уведомления (${path})`
|
||||
}
|
||||
},
|
||||
//Заголовок сообщения
|
||||
sSubject: {
|
||||
type: String,
|
||||
required: true,
|
||||
message: {
|
||||
type: path => `Заголовок сообщения (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||
required: path => `Не указан заголовок сообщения (${path})`
|
||||
}
|
||||
},
|
||||
//Текст уведомления
|
||||
sMessage: {
|
||||
type: String,
|
||||
required: true,
|
||||
message: {
|
||||
type: path => `Текст уведомления (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||
required: path => `Не указан текст уведомления (${path})`
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//Схема валидации параметров функции запуска контроллера
|
||||
exports.startController = new Schema({
|
||||
//Список обслуживаемых сервисов
|
||||
|
68
models/prms_utils.js
Normal file
68
models/prms_utils.js
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
Сервис интеграции ПП Парус 8 с WEB API
|
||||
Модели данных: описатели параметров вспомогательных функций (модуль utils.js)
|
||||
*/
|
||||
|
||||
//----------------------
|
||||
// Подключение библиотек
|
||||
//----------------------
|
||||
|
||||
const Schema = require("validate"); //Схемы валидации
|
||||
const { mail } = require("./obj_config"); //Схемы валидации конфигурации сервера приложений
|
||||
const { validateMailList } = require("./common"); //Общие объекты валидации моделей данных
|
||||
|
||||
//-------------
|
||||
// Тело модуля
|
||||
//-------------
|
||||
|
||||
//Валидация списка адресов E-Mail для отправки уведомления
|
||||
const validateTo = val => {
|
||||
return validateMailList(val);
|
||||
};
|
||||
|
||||
//------------------
|
||||
// Интерфейс модуля
|
||||
//------------------
|
||||
|
||||
//Схема валидации параметров функции отправки E-Mail
|
||||
exports.sendMail = new Schema({
|
||||
//Параметры отправки E-Mail уведомлений
|
||||
mail: {
|
||||
schema: mail,
|
||||
required: true,
|
||||
message: {
|
||||
required: path => `Не указаны параметры отправки E-Mail уведомлений (${path})`
|
||||
}
|
||||
},
|
||||
//Список адресов E-Mail для отправки уведомления
|
||||
sTo: {
|
||||
type: String,
|
||||
required: true,
|
||||
use: { validateTo },
|
||||
message: {
|
||||
type: path =>
|
||||
`Список адресов E-Mail для отправки уведомления (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||
required: path => `Не указан cписок адресов E-Mail для отправки уведомления (${path})`,
|
||||
validateTo: path =>
|
||||
`Неверный формат списка адресов E-Mail для отправки уведомления (${path}), для указания нескольких адресов следует использовать запятую в качестве разделителя (без пробелов)`
|
||||
}
|
||||
},
|
||||
//Заголовок сообщения
|
||||
sSubject: {
|
||||
type: String,
|
||||
required: true,
|
||||
message: {
|
||||
type: path => `Заголовок сообщения (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||
required: path => `Не указан заголовок сообщения (${path})`
|
||||
}
|
||||
},
|
||||
//Текст уведомления
|
||||
sMessage: {
|
||||
type: String,
|
||||
required: true,
|
||||
message: {
|
||||
type: path => `Текст уведомления (${path}) имеет некорректный тип данных (ожидалось - String)`,
|
||||
required: path => `Не указан текст уведомления (${path})`
|
||||
}
|
||||
}
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user