diff --git a/config/default.js b/config/default.js index 811398b..b723fbc 100644 --- a/config/default.js +++ b/config/default.js @@ -107,6 +107,7 @@ const _config = { }, discord: { + disableUrlEmbeds: true, // wraps any URLs detected in angle-brackets (<>) before sending to Discord userScriptOutputChannelId: '', privMsgChannelStalenessTimeMinutes: 720, privMsgChannelStalenessRemovalAlert: 0.1, // remaining of privMsgChannelStalenessTimeMinutes @@ -175,7 +176,7 @@ const _config = { enabled: false, port: 4242, proto: 'https', - host: "localhost", + host: 'localhost', fqdn: os.hostname(), ttlSecs: 30 * 60, staticDir: HTTP_STATIC_DIR, diff --git a/discord.js b/discord.js index 67f482d..5999900 100644 --- a/discord.js +++ b/discord.js @@ -27,6 +27,7 @@ const { scopedRedisClient, fmtDuration } = require('./util'); +const { wrapUrls } = require('./lib/wrapUrls'); require('./logger')('discord'); require('./lib/promRedisExport')('discord'); @@ -335,7 +336,7 @@ client.once('ready', async () => { } if (!raw) { - s = replaceIrcEscapes(s); + s = wrapUrls(replaceIrcEscapes(s)); } toSend = formatForAllowedSpeakerResponse(s, raw); @@ -447,7 +448,7 @@ client.once('ready', async () => { const privMsg = '_(Only visible to you)_'; if (!raw) { - msgFormatted = `${privMsg} ${msgFormatted}`; + msgFormatted = `${privMsg} ${!chan.__drcSend ? wrapUrls(msgFormatted) : msgFormatted}`; } await _realSender(msgFormatted, raw); diff --git a/discord/ipcMessages/irc-channelJoined.js b/discord/ipcMessages/irc-channelJoined.js index d00ef8e..dcfd5a9 100644 --- a/discord/ipcMessages/irc-channelJoined.js +++ b/discord/ipcMessages/irc-channelJoined.js @@ -10,6 +10,7 @@ const { replaceIrcEscapes, scopedRedisClient } = require('../../util'); +const { wrapUrls } = require('../../lib/wrapUrls'); const { AvatarGenerators, createAvatarName } = require('../avatarGenerators'); @@ -40,7 +41,7 @@ module.exports = async function (parsed, context) { } msgChan.__drcSend = (s) => { - msgChan.send(s) + msgChan.send(wrapUrls(s)) .catch((err) => console.error(`send on ${joined.channel} failed! "${err.message}"`, err.stack, parsed, JSON.stringify(err))); }; @@ -167,7 +168,7 @@ module.exports = async function (parsed, context) { } } - let content = replaceIrcEscapes(e.message).trim(); + let content = wrapUrls(replaceIrcEscapes(e.message).trim()); if (e.type === 'action') { content = `_${content}_`; diff --git a/discord/ipcMessages/irc-notice.js b/discord/ipcMessages/irc-notice.js index af0622a..1d96e81 100644 --- a/discord/ipcMessages/irc-notice.js +++ b/discord/ipcMessages/irc-notice.js @@ -14,6 +14,7 @@ const { persistPmChan } = require('../common'); const { MessageEmbed, MessageActionRow, MessageButton } = require('discord.js'); +const { wrapUrls } = require('../../lib/wrapUrls'); module.exports = async function (parsed, context) { const { @@ -150,7 +151,8 @@ module.exports = async function (parsed, context) { } const msChar = config.user.monospacePrivmsgs ? '`' : ''; - const msg = msChar + isIgnored + e.message + isIgnored + msChar; + const msg = msChar + isIgnored + wrapUrls(e.message) + isIgnored + msChar; + if (msg.length && !e.message.match(/^\s*$/g)) { try { await client.channels.cache.get(chanId)?.send(msg); diff --git a/discord/userCommands/config.js b/discord/userCommands/config.js index b161508..82a20ef 100644 --- a/discord/userCommands/config.js +++ b/discord/userCommands/config.js @@ -3,13 +3,16 @@ const config = require('config'); const { PREFIX } = require('../../util'); const { formatKVs } = require('../common'); +function redactedConfig () { + return config._replace(Object.assign({}, config), config._secretKeys, '**'); +} + async function userCommandConfig (context, ...a) { const key = PREFIX + ':userConfig'; switch (a[0]) { case 'get': - return '\n\n' + formatKVs(_.get( - config._replace(Object.assign({}, config), config._secretKeys, '**'), a[1])); + return '\n\n' + formatKVs(_.get(redactedConfig(), a[1])); case 'set': { @@ -31,7 +34,7 @@ async function userCommandConfig (context, ...a) { await context.redis.set(key, JSON.stringify(config.user)); } - return '\n' + formatKVs(_.get(config, ppathArr.length ? ppathArr.join('.') : a[1])); + return '\n' + formatKVs(_.get(redactedConfig(), ppathArr.length ? ppathArr.join('.') : a[1])); } case 'load': diff --git a/http.js b/http.js index 197a97a..3b50489 100644 --- a/http.js +++ b/http.js @@ -273,7 +273,7 @@ redisListener.subscribe(PREFIX, (err) => { app.close(); }); - app.listen({host: config.http.host, port: config.http.port}, (err, addr) => { + app.listen({ host: config.http.host, port: config.http.port }, (err, addr) => { if (err) { throw err; } diff --git a/lib/wrapUrls.js b/lib/wrapUrls.js new file mode 100644 index 0000000..29defed --- /dev/null +++ b/lib/wrapUrls.js @@ -0,0 +1,18 @@ +const extractUrls = require('extract-urls'); +const config = require('config'); + +function wrapUrls (text, wrapPrefix = '<', wrapPostfix = '>', checkIfEnabled = true) { + if (typeof (text) !== 'string') { + return text; + } + + if (checkIfEnabled && !config.discord.disableUrlEmbeds) { + return text; + } + + return extractUrls(text)?.reduce((ostr, url) => ostr.replace(url, `${wrapPrefix}${url}${wrapPostfix}`), text) ?? text; +} + +module.exports = { + wrapUrls +}; diff --git a/package-lock.json b/package-lock.json index dbd0c70..aa60f9e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "discord-api-types": "^0.37.24", "discord.js": "^13.3.1", "eslint": "^7.32.0", + "extract-urls": "^1.4.0", "fastify": "^3.29.4", "inquirer": "^8.2.0", "ioredis": "^5.3.0", @@ -4336,6 +4337,14 @@ "node": ">=0.10.0" } }, + "node_modules/extract-urls": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/extract-urls/-/extract-urls-1.4.0.tgz", + "integrity": "sha512-x8OnCTbXW/I4BkdPeKuw9/1rThb9yoPRrKeYKafuSEEJ2epthzm/eSI2jYgZ0g2GiSydj2QGSogsJMlOi9isQA==", + "engines": { + "node": ">=10" + } + }, "node_modules/fast-decode-uri-component": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", @@ -12970,6 +12979,11 @@ } } }, + "extract-urls": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/extract-urls/-/extract-urls-1.4.0.tgz", + "integrity": "sha512-x8OnCTbXW/I4BkdPeKuw9/1rThb9yoPRrKeYKafuSEEJ2epthzm/eSI2jYgZ0g2GiSydj2QGSogsJMlOi9isQA==" + }, "fast-decode-uri-component": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", diff --git a/package.json b/package.json index 4a5deb0..dec6e6a 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "discord-api-types": "^0.37.24", "discord.js": "^13.3.1", "eslint": "^7.32.0", + "extract-urls": "^1.4.0", "fastify": "^3.29.4", "inquirer": "^8.2.0", "ioredis": "^5.3.0",