UNPKG

openhim-core

Version:

The OpenHIM core application that provides logging and routing of http requests

282 lines (216 loc) 9.42 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.processAuditMeta = processAuditMeta; exports.processAudit = processAudit; exports.sendAuditEvent = sendAuditEvent; var _winston = _interopRequireDefault(require("winston")); var _glossy = require("glossy"); var _xml2js = require("xml2js"); var _dgram = _interopRequireDefault(require("dgram")); var _tls = _interopRequireDefault(require("tls")); var _net = _interopRequireDefault(require("net")); var _audits = require("./model/audits"); var tlsAuthentication = _interopRequireWildcard(require("./middleware/tlsAuthentication")); var _config = require("./config"); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } _config.config.auditing = _config.config.get('auditing'); const { firstCharLowerCase } = require('xml2js').processors; function parseAuditRecordFromXML(xml, callback) { // DICOM mappers function csdCodeToCode(name) { if (name === 'csd-code') { return 'code'; } return name; } function originalTextToDisplayName(name) { if (name === 'originalText') { return 'displayName'; } return name; } const options = { mergeAttrs: true, explicitArray: false, tagNameProcessors: [firstCharLowerCase], attrNameProcessors: [firstCharLowerCase, csdCodeToCode, originalTextToDisplayName] }; return (0, _xml2js.parseString)(xml, options, (err, result) => { if (err) { return callback(err); } if (!(result != null ? result.auditMessage : undefined)) { return callback(new Error('Document is not a valid AuditMessage')); } const audit = {}; if (result.auditMessage.eventIdentification) { audit.eventIdentification = result.auditMessage.eventIdentification; } audit.activeParticipant = []; if (result.auditMessage.activeParticipant) { // xml2js will only use an array if multiple items exist (explicitArray: false), else it's an object if (result.auditMessage.activeParticipant instanceof Array) { for (const ap of Array.from(result.auditMessage.activeParticipant)) { audit.activeParticipant.push(ap); } } else { audit.activeParticipant.push(result.auditMessage.activeParticipant); } } if (result.auditMessage.auditSourceIdentification) { audit.auditSourceIdentification = result.auditMessage.auditSourceIdentification; } audit.participantObjectIdentification = []; if (result.auditMessage.participantObjectIdentification) { // xml2js will only use an array if multiple items exist (explicitArray: false), else it's an object if (result.auditMessage.participantObjectIdentification instanceof Array) { for (const poi of Array.from(result.auditMessage.participantObjectIdentification)) { audit.participantObjectIdentification.push(poi); } } else { audit.participantObjectIdentification.push(result.auditMessage.participantObjectIdentification); } } return callback(null, audit); }); } function codeInArray(code, arr) { return arr.map(a => a.code).includes(code); } function processAuditMeta(audit, callback) { _audits.AuditMetaModel.findOne({}, (err, auditMeta) => { if (err) { _winston.default.error(err); return callback(); } if (!auditMeta) { auditMeta = new _audits.AuditMetaModel(); } if (audit.eventIdentification != null && audit.eventIdentification.eventTypeCode != null && audit.eventIdentification.eventTypeCode.code && !codeInArray(audit.eventIdentification.eventTypeCode.code, auditMeta.eventType)) { auditMeta.eventType.push(audit.eventIdentification.eventTypeCode); } if (audit.eventIdentification != null && audit.eventIdentification.eventID != null && audit.eventIdentification.eventID && !codeInArray(audit.eventIdentification.eventID.code, auditMeta.eventID)) { auditMeta.eventID.push(audit.eventIdentification.eventID); } if (audit.activeParticipant) { for (const activeParticipant of Array.from(audit.activeParticipant)) { if ((activeParticipant.roleIDCode != null ? activeParticipant.roleIDCode.code : undefined) && !codeInArray(activeParticipant.roleIDCode.code, auditMeta.activeParticipantRoleID)) { auditMeta.activeParticipantRoleID.push(activeParticipant.roleIDCode); } } } if (audit.participantObjectIdentification) { for (const participantObject of Array.from(audit.participantObjectIdentification)) { if ((participantObject.participantObjectIDTypeCode != null ? participantObject.participantObjectIDTypeCode.code : undefined) && !codeInArray(participantObject.participantObjectIDTypeCode.code, auditMeta.participantObjectIDTypeCode)) { auditMeta.participantObjectIDTypeCode.push(participantObject.participantObjectIDTypeCode); } } } if ((audit.auditSourceIdentification != null ? audit.auditSourceIdentification.auditSourceID : undefined) && !Array.from(auditMeta.auditSourceID).includes(audit.auditSourceIdentification.auditSourceID)) { auditMeta.auditSourceID.push(audit.auditSourceIdentification.auditSourceID); } auditMeta.save(err => { if (err) { _winston.default.error(err); } return callback(); }); }); } function processAudit(msg, callback) { if (callback == null) { callback = function () {}; } const parsedMsg = _glossy.Parse.parse(msg); if (!parsedMsg || !parsedMsg.message) { _winston.default.info('Invalid message received'); return callback(); } parseAuditRecordFromXML(parsedMsg.message, (xmlErr, result) => { const audit = new _audits.AuditModel(result); audit.rawMessage = msg; audit.syslog = parsedMsg; delete audit.syslog.originalMessage; delete audit.syslog.message; return audit.save(saveErr => { if (saveErr) { _winston.default.error(`An error occurred while processing the audit entry: ${saveErr}`); } if (xmlErr) { _winston.default.info(`Failed to parse message as an AuditMessage XML document: ${xmlErr}`); } processAuditMeta(audit, callback); }); }); } function sendUDPAudit(msg, callback) { const client = _dgram.default.createSocket('udp4'); client.send(msg, 0, msg.length, _config.config.auditing.auditEvents.port, _config.config.auditing.auditEvents.host, err => { client.close(); return callback(err); }); } const sendTLSAudit = (msg, callback) => tlsAuthentication.getServerOptions(true, (err, options) => { if (err) { return callback(err); } const client = _tls.default.connect(_config.config.auditing.auditEvents.port, _config.config.auditing.auditEvents.host, options, () => { const { rejectUnauthorized = true } = options; if (rejectUnauthorized && !client.authorized) { return callback(client.authorizationError); } client.write(`${msg.length} ${msg}`); return client.end(); }); client.resume(); client.on('error', err => _winston.default.error(err)); return client.on('close', () => callback()); }); function sendTCPAudit(msg, callback) { const client = _net.default.connect(_config.config.auditing.auditEvents.port, _config.config.auditing.auditEvents.host, () => { client.write(`${msg.length} ${msg}`); return client.end(); }); client.resume(); client.on('error', err => { if (err) { return callback(err); } }); return client.on('close', () => callback()); } // Send an audit event function sendAuditEvent(msg, callback) { if (callback == null) { callback = function () {}; } function done(err) { if (err) { _winston.default.error(err); } return callback(); } if ((_config.config.auditing != null ? _config.config.auditing.auditEvents : undefined) == null) { return done(new Error('Unable to record audit event: Missing config.auditing.auditEvents')); } switch (_config.config.auditing.auditEvents.interface) { case 'internal': return processAudit(msg, done); case 'udp': return sendUDPAudit(msg, done); case 'tls': return sendTLSAudit(msg, done); case 'tcp': return sendTCPAudit(msg, done); default: return done(new Error(`Invalid audit event interface '${_config.config.auditing.auditEvents.interface}'`)); } } //# sourceMappingURL=auditing.js.map