Version 2.2.0

Update dependencies (security fix)
Fix lint errors
This commit is contained in:
nioc 2022-09-28 01:18:01 +02:00
parent e7f8967176
commit 061725526b
11 changed files with 9952 additions and 4692 deletions

View file

@ -15,7 +15,7 @@ module.exports = function Configuration (logger, configPath = null) {
configPath = './lib/config/config.json'
}
try {
let data = require('fs').readFileSync(configPath)
const data = require('fs').readFileSync(configPath)
config = JSON.parse(data)
} catch (error) {
logger.fatal(`Invalid configuration file: ${error.message}, current directory is: ${process.cwd()}`)

View file

@ -10,7 +10,7 @@
*/
module.exports = (logger, xmpp) => {
let nodeCleanup = require('node-cleanup')
const nodeCleanup = require('node-cleanup')
nodeCleanup(function (exitCode, signal) {
logger.warn(`Received ${exitCode}/${signal} (application is closing), disconnect from XMPP server`)
try {

View file

@ -25,7 +25,7 @@ module.exports = () => {
}
// add appenders
let appenders = []
const appenders = []
if (config.file.active) {
const fs = require('fs')
if (!fs.existsSync(config.file.path)) {
@ -73,7 +73,7 @@ module.exports = () => {
}
},
categories: {
default: { appenders: appenders, level: 'info' }
default: { appenders, level: 'info' }
}
})
logger = log4js.getLogger()

View file

@ -10,7 +10,7 @@
*/
module.exports = async (logger, config, xmpp, user, destination, message, type, code) => {
let webhook = config.getOutgoingWebhook(code)
const webhook = config.getOutgoingWebhook(code)
if (!webhook) {
logger.warn(`There is no webhook with code "${code}"`)
throw new Error(`There is no webhook with code "${code}"`)
@ -18,7 +18,7 @@ module.exports = async (logger, config, xmpp, user, destination, message, type,
const { promisify } = require('util')
const request = promisify(require('request'))
// request.debug = true
let options = {
const options = {
method: 'POST',
url: webhook.url,
strictSSL: webhook.strictSSL
@ -50,7 +50,7 @@ module.exports = async (logger, config, xmpp, user, destination, message, type,
logger.trace('Content-type: application/x-www-form-urlencoded')
options.form = {
from: user,
message: message,
message,
channel: destination
}
logger.trace('Outgoing webhook request:', options.form)
@ -59,7 +59,7 @@ module.exports = async (logger, config, xmpp, user, destination, message, type,
logger.trace('Content-type: application/json')
options.json = {
from: user,
message: message,
message,
channel: destination
}
logger.trace('Outgoing webhook request:', options.json)

View file

@ -1,10 +1,10 @@
'use strict'
// create default logger
let logger = require('./logger')()
const logger = require('./logger')()
// get configuration
let config = require('./config')(logger)
const config = require('./config')(logger)
// update logger with configuration
logger.updateConfig(config.logger)

View file

@ -18,7 +18,7 @@ module.exports = (logger, config, xmpp) => {
const port = config.listener.port || 8000
const portSsl = config.listener.ssl.port || 8001
var webhook = express()
const webhook = express()
// handle connection from proxy (get IP in 'X-Forwarded-For' header)
webhook.set('trust proxy', true)
@ -57,7 +57,7 @@ module.exports = (logger, config, xmpp) => {
// handle post request
webhook.post(config.listener.path + '/*', (req, res) => {
logger.info(`Incoming webhook from ${req.auth.user}`)
let webhook = config.getWebhookAction(req.path)
const webhook = config.getWebhookAction(req.path)
if (!webhook) {
logger.error(`Webhook received: ${req.path}, not found`)
return res.status(404).send('Webhook not found')
@ -65,21 +65,20 @@ module.exports = (logger, config, xmpp) => {
logger.debug(`Webhook received: ${webhook.path}, start action: ${webhook.action}`)
logger.trace(req.body)
switch (webhook.action) {
case 'send_xmpp_message':
case 'send_xmpp_message': {
// get destination
if ('destination' in req.body === false) {
logger.error('Destination not found')
return res.status(400).send('Destination not found')
}
let destination = req.body.destination
const destination = req.body.destination
// get message
if ('message' in req.body === false) {
logger.error('Message not found')
return res.status(400).send('Message not found')
}
let message = req.body.message
const message = req.body.message
// check if destination is a group chat
const type = config.xmpp.rooms.some((room) => room.id === destination) ? 'groupchat' : 'chat'
@ -88,17 +87,17 @@ module.exports = (logger, config, xmpp) => {
logger.trace(`Send to ${destination} (group:${type}) following message :\r\n${message}`)
xmpp.send(destination, message, type)
.then(() => {
return res.status(200).send({ 'status': 'ok', destination })
return res.status(200).send({ status: 'ok', destination })
})
.catch(() => {
return res.status(500).send('Could not send message')
})
break
}
case 'send_xmpp_template':
case 'send_xmpp_template': {
// bind data in template
let msg = webhook.template.replace(/\$\{(.+?)\}/g, (match, $1) => {
const msg = webhook.template.replace(/\$\{(.+?)\}/g, (match, $1) => {
return jmespath.search(req.body, $1) || ''
})
logger.trace(`Message:\r\n${msg}`)
@ -114,6 +113,7 @@ module.exports = (logger, config, xmpp) => {
return res.status(500).send('Could not send message')
})
break
}
default:
return res.status(204).send()
@ -133,10 +133,10 @@ module.exports = (logger, config, xmpp) => {
// get IP v4 addresses and prepare endpoints for output
let addresses = []
const networkInterfaces = require('os').networkInterfaces()
for (let ifaceName in networkInterfaces) {
for (const ifaceName in networkInterfaces) {
addresses = addresses.concat(networkInterfaces[ifaceName].reduce((add, iface) => {
if (iface['family'] === 'IPv4') {
add.push(iface['address'])
if (iface.family === 'IPv4') {
add.push(iface.address)
}
return add
}, []))
@ -166,7 +166,7 @@ module.exports = (logger, config, xmpp) => {
try {
fs.accessSync(config.listener.ssl.certPath, fs.constants.R_OK)
logger.debug('Can read certificate')
let credentials = {
const credentials = {
key: fs.readFileSync(config.listener.ssl.keyPath),
cert: fs.readFileSync(config.listener.ssl.certPath)
}

View file

@ -55,7 +55,7 @@ module.exports = (logger, config) => {
})
// join rooms
config.xmpp.rooms.forEach(function (room) {
let occupantJid = room.id + '/' + address.local
const occupantJid = room.id + '/' + address.local
logger.debug(`Join room: ${room.id} ('${occupantJid}')`)
const stanza = xml(
'presence', {
@ -78,16 +78,16 @@ module.exports = (logger, config) => {
// not a message, do nothing
return
}
let type = stanza.attrs.type
const type = stanza.attrs.type
switch (type) {
case 'chat':
case 'groupchat':
let body = stanza.getChild('body')
case 'groupchat': {
const body = stanza.getChild('body')
if (!body) {
// empty body, do nothing
return
}
let fromJid = jid(stanza.attrs.from)
const fromJid = jid(stanza.attrs.from)
// for chat, "to" and "replyTo" must be something like "user@domain.ltd", "from" is local part "user"
let to = this.jid.bare()
let from = fromJid.local
@ -102,15 +102,15 @@ module.exports = (logger, config) => {
return
}
}
let message = body.text()
const message = body.text()
// handle message delivery receipts for chat
if (type === 'chat') {
let request = stanza.getChild('request')
const request = stanza.getChild('request')
if (request &&
request.attrs.xmlns &&
request.attrs.xmlns === 'urn:xmpp:receipts' &&
stanza.attrs.id) {
logger.debug(`Message delivery receipt is requested and will be processed`)
logger.debug('Message delivery receipt is requested and will be processed')
const receiptStanza = xml(
'message', {
to: fromJid
@ -127,7 +127,7 @@ module.exports = (logger, config) => {
}
logger.info(`Incoming ${type} message from ${from} (${fromJid.toString()}) to ${to}`)
logger.debug(`Message: "${message.replace(/\n|\r/g, ' ')}"`)
let xmppHook = config.getXmppHookAction(to.toString())
const xmppHook = config.getXmppHookAction(to.toString())
if (!xmppHook) {
logger.error(`There is no action for incoming ${type} message to: "${to}"`)
return
@ -145,6 +145,7 @@ module.exports = (logger, config) => {
}
break
}
}
})
// handle status

14531
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
{
"name": "xmpp-bot",
"version": "2.1.0",
"version": "2.2.0",
"description": "XMPP bot",
"main": "./lib/server.js",
"scripts": {
@ -12,7 +12,7 @@
"coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls"
},
"engines": {
"node": ">= 10.0.0"
"node": ">= 12.4.0"
},
"author": "nioc <dev@nioc.eu>",
"license": "AGPL-3.0-or-later",
@ -22,30 +22,29 @@
},
"private": true,
"dependencies": {
"@xmpp/client": "^0.8.0",
"body-parser": "^1.19.0",
"express": "^4.17.1",
"express-basic-auth": "^1.2.0",
"jmespath": "^0.15.0",
"log4js": "^4.5.1",
"morgan": "^1.9.1",
"@xmpp/client": "^0.13.1",
"body-parser": "^1.20.0",
"express": "^4.18.1",
"express-basic-auth": "^1.2.1",
"jmespath": "^0.16.0",
"log4js": "^6.6.1",
"morgan": "^1.10.0",
"node-cleanup": "^2.1.2",
"request": "^2.88.0"
"request": "^2.88.2"
},
"devDependencies": {
"chai": "^4.2.0",
"coveralls": "^3.0.8",
"eslint": "^6.7.0",
"eslint-config-standard": "^12.0.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-node": "^9.2.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"mocha": "^6.2.2",
"chai": "^4.3.6",
"coveralls": "^3.0.9",
"eslint": "^8.24.0",
"eslint-config-standard": "^17.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.0.1",
"mocha": "^10.0.0",
"mock-require": "^3.0.3",
"nock": "^11.7.0",
"nodemon": "^1.19.4",
"nyc": "^14.1.1",
"sinon": "^7.5.0"
"nock": "^13.2.9",
"nodemon": "^2.0.20",
"nyc": "^15.1.0",
"sinon": "^14.0.0"
}
}

View file

@ -1,5 +1,6 @@
'use strict'
/* eslint-disable handle-callback-err */
/* eslint-disable n/handle-callback-err */
/* eslint-disable prefer-regex-literals */
process.env.NODE_ENV = 'production'
require('chai').should()

View file

@ -74,12 +74,12 @@ describe('XMPP component', () => {
it('Should connect to XMPP server and join rooms when application start', (done) => {
sinon.assert.called(xmppSendStub)
// 1 "send" call for presence and n "send" calls for joining rooms
let roomsLength = config.xmpp.rooms.length
const roomsLength = config.xmpp.rooms.length
sinon.assert.callCount(xmppSendStub, roomsLength + 1)
for (let index = 1; index < roomsLength + 1; index++) {
const args = xmppSendStub.args[index]
args.should.have.length(1)
let occupantJid = config.xmpp.rooms[index - 1].id + '/' + 'bot'
const occupantJid = config.xmpp.rooms[index - 1].id + '/' + 'bot'
const stanza = xml(
'presence', {
to: occupantJid
@ -353,7 +353,7 @@ describe('XMPP component', () => {
})
it('Should call xmpp/client.send() with valid stanza', (done) => {
sinon.assert.calledOnce(xmppSendStub)
let stanza = xml(
const stanza = xml(
'message', {
to: 'someone@domain-xmpp.ltd',
type: 'chat'