From a7c11f856a9b28777f6f0b8c24b4bdb2fdcd6388 Mon Sep 17 00:00:00 2001 From: nakajimayoshi Date: Fri, 12 Jul 2024 21:52:13 +0900 Subject: [PATCH] upgrade bot with profanity filter, change hosting service --- .dockerignore | 10 +- .gitignore | 3 + Dockerfile | 4 +- docker-compose.yaml | 35 ++++ package-lock.json | 331 +++++++++++++++++++++++++++------ package.json | 2 + src/commands/memes/cowsay.ts | 13 +- src/commands/moderation/ban.ts | 5 +- src/commands/utils/metar.ts | 3 +- src/commands/utils/station.ts | 3 +- src/handlers/ban.ts | 7 +- src/index.ts | 15 +- src/lib/logger.ts | 7 +- src/secrets.ts | 19 ++ 14 files changed, 380 insertions(+), 77 deletions(-) create mode 100644 docker-compose.yaml create mode 100644 src/secrets.ts diff --git a/.dockerignore b/.dockerignore index 5f9fe0c..bc121b4 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,6 +3,14 @@ build charts node_modules +.env Dockerfile -.dockerignore \ No newline at end of file +.dockerignore + +# secrets +DEBUG_MODE.txt +DISCORD_TOKEN.txt +METAR_TOKEN.txt +NODE_ENV.txt +STATION_TOKEN.txt \ No newline at end of file diff --git a/.gitignore b/.gitignore index a90b519..5b76bdb 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ node_modules # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + +# docker-compose secrets +/*.txt \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 0a7874c..25e90a7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:16-alpine as builder +FROM node:22-alpine3.19 as builder WORKDIR /app ENV NODE_ENV=development @@ -12,7 +12,7 @@ COPY src/ src/ RUN npm run build:typescript -FROM node:16-alpine +FROM node:22-alpine3.19 WORKDIR /app ENV NODE_ENV=production diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..9af9c44 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,35 @@ +services: + app: + restart: always + build: + dockerfile: Dockerfile + context: . + container_name: "heavy-division-bot" + secrets: + - debug_mode + - node_env + - discord_token + - metar_token + - station_token + - ban_appeal_url + environment: + DEBUG_MODE: /run/secrets/debug_mode + NODE_ENV: /run/secrets/node_env + DISCORD_TOKEN: /run/secrets/discord_token + METAR_TOKEN: /run/secrets/metar_token + STATION_TOKEN: /run/secrets/station_token + BAN_APPEAL_URL: /run/secrets/ban_appeal_url + +secrets: + debug_mode: + file: ./DEBUG_MODE.txt + node_env: + file: ./NODE_ENV.txt + discord_token: + file: ./DISCORD_TOKEN.txt + metar_token: + file: ./METAR_TOKEN.txt + station_token: + file: ./STATION_TOKEN.txt + ban_appeal_url: + file: ./BAN_APPEAL_URL.txt \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7951864..b12ea74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,12 +10,14 @@ "license": "AGPL 3.0", "dependencies": { "@elastic/ecs-winston-format": "^1.1.0", + "@types/bad-words": "^3.0.3", "bad-words": "^3.0.4", "cowsay": "^1.5.0", "discord.js": "^14.0.3", "elastic-apm-node": "^3.35.0", "express": "^4.17.3", "got": "^12.1.0", + "leo-profanity": "^1.7.0", "moment": "^2.29.4", "mongoose": "^7.1.0", "request": "^2.88.2", @@ -480,6 +482,11 @@ "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", "dev": true }, + "node_modules/@types/bad-words": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/bad-words/-/bad-words-3.0.3.tgz", + "integrity": "sha512-jYdpTxDOJ+EENnsCwt8cOZhV/+4+qcwhks1igrOSg4zwwA17rsPqLsZpTo1l+OwViNu+5SPus0v5g7iGx+ofzA==" + }, "node_modules/@types/cacheable-request": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", @@ -1249,12 +1256,18 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1669,11 +1682,28 @@ "node": ">=10" } }, - "node_modules/define-properties": { + "node_modules/define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -1959,6 +1989,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-shim-unscopables": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", @@ -2898,6 +2947,12 @@ "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==" }, + "node_modules/french-badwords-list": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/french-badwords-list/-/french-badwords-list-1.0.7.tgz", + "integrity": "sha512-H1ziKs2PJh2+UXZ9oCGJ/rRQpsI9NBykGf2Sc7WaKaj1OnWFuBXfsvANTdRcfVmOghGQaUmRyZ1hJOPbDpy04Q==", + "optional": true + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -2927,9 +2982,12 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { "version": "1.1.5", @@ -2971,13 +3029,18 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3095,6 +3158,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/got": { "version": "12.2.0", "resolved": "https://registry.npmjs.org/got/-/got-12.2.0.tgz", @@ -3171,11 +3245,22 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dependencies": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3193,11 +3278,11 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -3206,6 +3291,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", @@ -3784,6 +3880,15 @@ "language-subtag-registry": "~0.3.2" } }, + "node_modules/leo-profanity": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/leo-profanity/-/leo-profanity-1.7.0.tgz", + "integrity": "sha512-88j1R08jrQzOib9Yxk4nxrzMlrHJi3DzFzAmv0L4APQ+ciGEfJ1rftVEvFjoqL0m+0KGFL3csQGRlxXGnYrA7w==", + "optionalDependencies": { + "french-badwords-list": "^1.0.6", + "russian-bad-words": "^0.5.0" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -5022,6 +5127,15 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/russian-bad-words": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/russian-bad-words/-/russian-bad-words-0.5.0.tgz", + "integrity": "sha512-euNvEYki6iYYpkNbeudW+lEMMYGEmN7EBwVF8ezlbv0bZoQpVYB7W10cCeUIGV7Ed50sJynLQ0c559q5iI0ejQ==", + "optional": true, + "engines": { + "node": ">=10" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -5140,6 +5254,22 @@ "resolved": "https://registry.npmjs.org/set-cookie-serde/-/set-cookie-serde-1.0.0.tgz", "integrity": "sha512-Vq8e5GsupfJ7okHIvEPcfs5neCo7MZ1ZuWrO3sllYi3DOWt6bSSCpADzqXjz3k0fXehnoFIrmmhty9IN6U6BXQ==" }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -5815,9 +5945,9 @@ } }, "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" }, "node_modules/tsutils": { "version": "3.21.0", @@ -6575,6 +6705,11 @@ "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", "dev": true }, + "@types/bad-words": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/bad-words/-/bad-words-3.0.3.tgz", + "integrity": "sha512-jYdpTxDOJ+EENnsCwt8cOZhV/+4+qcwhks1igrOSg4zwwA17rsPqLsZpTo1l+OwViNu+5SPus0v5g7iGx+ofzA==" + }, "@types/cacheable-request": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", @@ -7160,12 +7295,15 @@ } }, "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" } }, "callsites": { @@ -7474,11 +7612,22 @@ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" }, - "define-properties": { + "define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "requires": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } @@ -7710,6 +7859,19 @@ "unbox-primitive": "^1.0.2" } }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, "es-shim-unscopables": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", @@ -8450,6 +8612,12 @@ "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==" }, + "french-badwords-list": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/french-badwords-list/-/french-badwords-list-1.0.7.tgz", + "integrity": "sha512-H1ziKs2PJh2+UXZ9oCGJ/rRQpsI9NBykGf2Sc7WaKaj1OnWFuBXfsvANTdRcfVmOghGQaUmRyZ1hJOPbDpy04Q==", + "optional": true + }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -8469,9 +8637,9 @@ "optional": true }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "function.prototype.name": { "version": "1.1.5", @@ -8501,13 +8669,15 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" } }, "get-stdin": { @@ -8583,6 +8753,14 @@ "slash": "^3.0.0" } }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "got": { "version": "12.2.0", "resolved": "https://registry.npmjs.org/got/-/got-12.2.0.tgz", @@ -8637,24 +8815,37 @@ "dev": true }, "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "requires": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" } }, + "has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==" + }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "requires": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" + } + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "requires": { + "function-bind": "^1.1.2" } }, "http-cache-semantics": { @@ -9087,6 +9278,15 @@ "language-subtag-registry": "~0.3.2" } }, + "leo-profanity": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/leo-profanity/-/leo-profanity-1.7.0.tgz", + "integrity": "sha512-88j1R08jrQzOib9Yxk4nxrzMlrHJi3DzFzAmv0L4APQ+ciGEfJ1rftVEvFjoqL0m+0KGFL3csQGRlxXGnYrA7w==", + "requires": { + "french-badwords-list": "^1.0.6", + "russian-bad-words": "^0.5.0" + } + }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -9989,6 +10189,12 @@ "queue-microtask": "^1.2.2" } }, + "russian-bad-words": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/russian-bad-words/-/russian-bad-words-0.5.0.tgz", + "integrity": "sha512-euNvEYki6iYYpkNbeudW+lEMMYGEmN7EBwVF8ezlbv0bZoQpVYB7W10cCeUIGV7Ed50sJynLQ0c559q5iI0ejQ==", + "optional": true + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -10090,6 +10296,19 @@ "resolved": "https://registry.npmjs.org/set-cookie-serde/-/set-cookie-serde-1.0.0.tgz", "integrity": "sha512-Vq8e5GsupfJ7okHIvEPcfs5neCo7MZ1ZuWrO3sllYi3DOWt6bSSCpADzqXjz3k0fXehnoFIrmmhty9IN6U6BXQ==" }, + "set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + } + }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -10601,9 +10820,9 @@ } }, "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" }, "tsutils": { "version": "3.21.0", diff --git a/package.json b/package.json index 557069d..9e1ed62 100644 --- a/package.json +++ b/package.json @@ -16,12 +16,14 @@ "license": "AGPL 3.0", "dependencies": { "@elastic/ecs-winston-format": "^1.1.0", + "@types/bad-words": "^3.0.3", "bad-words": "^3.0.4", "cowsay": "^1.5.0", "discord.js": "^14.0.3", "elastic-apm-node": "^3.35.0", "express": "^4.17.3", "got": "^12.1.0", + "leo-profanity": "^1.7.0", "moment": "^2.29.4", "mongoose": "^7.1.0", "request": "^2.88.2", diff --git a/src/commands/memes/cowsay.ts b/src/commands/memes/cowsay.ts index 8a525ce..051bd09 100644 --- a/src/commands/memes/cowsay.ts +++ b/src/commands/memes/cowsay.ts @@ -3,14 +3,25 @@ import { say } from 'cowsay'; import { CommandDefinition } from '../../lib/command'; import { CommandCategory } from '../../constants'; +import Filter from 'bad-words'; export const cowsay: CommandDefinition = { name: ['cowsay', 'cs'], description: 'Emulates the famous UNIX program `cowsay`.', category: CommandCategory.MEMES, - executor: (msg) => { + executor: async (msg) => { + + const filter = new Filter(); const text = msg.content.replace(/\.(cowsay|cs)\s*/, '').replace(/`/g, ''); + if (filter.isProfane(msg.content.trim())) { + await msg.channel.send('Watch your tongue!') + return; + } + + + + if (text) { return msg.channel.send(`\`\`\`\n${say(({ text }))}\n\`\`\``); } diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts index 1ec0e7a..34d3e7a 100644 --- a/src/commands/moderation/ban.ts +++ b/src/commands/moderation/ban.ts @@ -3,6 +3,7 @@ import moment from 'moment'; import { CommandDefinition } from '../../lib/command'; import { Channels, CommandCategory } from '../../constants'; import { makeEmbed, makeLines } from '../../lib/embed'; +import { BAN_APPEAL_URL } from '../../secrets'; const moderatableFailEmbed = makeEmbed({ color: Colors.Red, @@ -112,7 +113,7 @@ const dmEmbed = (formattedDate, moderator: User, reason: string) => makeEmbed({ { inline: false, name: 'Appeal', - value: `If you would like to appeal your ban, please fill out [this form.](${process.env.BAN_APPEAL_URL})`, + value: `If you would like to appeal your ban, please fill out [this form.](${BAN_APPEAL_URL})`, }, ], }); @@ -122,7 +123,7 @@ const noDM = (user: User) => makeEmbed({ description: makeLines([ `${user.toString()} has DMs closed or has no mutual servers with the bot`, '', - `Please remember to send the user the reason they were banned and the ban appeal form - ${process.env.BAN_APPEAL_URL}`, + `Please remember to send the user the reason they were banned and the ban appeal form - ${BAN_APPEAL_URL}`, ]), color: Colors.Red, }); diff --git a/src/commands/utils/metar.ts b/src/commands/utils/metar.ts index 8b5a6e9..7c72fb0 100644 --- a/src/commands/utils/metar.ts +++ b/src/commands/utils/metar.ts @@ -2,6 +2,7 @@ import request from 'request'; import { CommandDefinition } from '../../lib/command'; import { CommandCategory, Units, Colors } from '../../constants'; import { makeEmbed, makeLines } from '../../lib/embed'; +import { METAR_TOKEN } from '../../secrets'; export const metar: CommandDefinition = { name: 'metar', @@ -19,7 +20,7 @@ export const metar: CommandDefinition = { request({ method: 'GET', url: `https://avwx.rest/api/metar/${icaoArg}`, - headers: { Authorization: process.env.METAR_TOKEN }, + headers: { Authorization: METAR_TOKEN }, }, async (error, response, body) => { let metarEmbed; diff --git a/src/commands/utils/station.ts b/src/commands/utils/station.ts index 44e8f76..924cbbf 100644 --- a/src/commands/utils/station.ts +++ b/src/commands/utils/station.ts @@ -4,6 +4,7 @@ import request from 'request'; import { CommandDefinition } from '../../lib/command'; import { CommandCategory } from '../../constants'; import { makeEmbed, makeLines } from '../../lib/embed'; +import { STATION_TOKEN } from '../../secrets'; export const station: CommandDefinition = { name: 'station', @@ -21,7 +22,7 @@ export const station: CommandDefinition = { request({ method: 'GET', url: `https://avwx.rest/api/station/${icaoArg}`, - headers: { Authorization: process.env.STATION_TOKEN }, + headers: { Authorization: STATION_TOKEN }, }, async (error, response, body) => { let stationEmbed; diff --git a/src/handlers/ban.ts b/src/handlers/ban.ts index c5513cf..55eadf7 100644 --- a/src/handlers/ban.ts +++ b/src/handlers/ban.ts @@ -2,6 +2,7 @@ import { AuditLogEvent, bold, Colors, TextChannel, User } from 'discord.js'; import { Channels, ModLogsExclude } from '../constants'; import { makeEmbed, makeLines } from '../lib/embed'; import Logger from '../lib/logger'; +import { BAN_APPEAL_URL } from '../secrets'; const MAX_RETRIES = 5; const SLEEP_TIMER = 0.5 * 1000; @@ -17,7 +18,7 @@ const noLogEmbed = (user: User, guildName: string) => makeEmbed({ '', bold('NOTE - This was a non bot ban.'), '', - `Please remember to send the user the reason they were banned and the ban appeal form - ${process.env.BAN_APPEAL_URL}`, + `Please remember to send the user the reason they were banned and the ban appeal form - ${BAN_APPEAL_URL}`, ]), footer: { text: `User ID: ${user.id}` }, }); @@ -31,7 +32,7 @@ const userBannedEmbed = (user: User, executor: User, reason: string) => makeEmbe description: makeLines([ bold('NOTE - This was a non bot ban.'), '', - `Please remember to send the user the reason they were banned and the ban appeal form - ${process.env.BAN_APPEAL_URL}`, + `Please remember to send the user the reason they were banned and the ban appeal form - ${BAN_APPEAL_URL}`, ]), fields: [ { @@ -59,7 +60,7 @@ const userBannedIncompleteEmbed = (user: User) => makeEmbed({ description: makeLines([ bold('NOTE - This was a non bot ban.'), '', - `Please remember to send the user the reason they were banned and the ban appeal form - ${process.env.BAN_APPEAL_URL}`, + `Please remember to send the user the reason they were banned and the ban appeal form - ${BAN_APPEAL_URL}`, ]), fields: [ { diff --git a/src/index.ts b/src/index.ts index 2a08914..c7d86cc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,7 @@ import commands from './commands'; import { makeEmbed } from './lib/embed'; import Logger from './lib/logger'; import { connect } from './lib/db'; +import { DEBUG_MODE, DISCORD_TOKEN } from './secrets'; dotenv.config(); const apm = require('elastic-apm-node').start({ @@ -14,7 +15,7 @@ const apm = require('elastic-apm-node').start({ disableSend: true, }); -export const DEBUG_MODE = process.env.DEBUG_MODE === 'true'; +export const IS_DEBUG_MODE = DEBUG_MODE === 'true'; const client = new Client({ intents: [ 'Guilds', @@ -44,10 +45,10 @@ client.on('ready', () => { Logger.info(`Logged in as ${client.user.tag}!`); healthy = true; // Connect to database - if (process.env.MONGODB_URL) { - connect(process.env.MONGODB_URL) - .catch(Logger.error); - } + // if (process.env.MONGODB_URL) { + // connect(process.env.MONGODB_URL) + // .catch(Logger.error); + // } }); client.on('disconnect', () => { @@ -96,7 +97,7 @@ client.on('messageCreate', async (msg) => { const errorEmbed = makeEmbed({ color: Colors.Red, title: 'Error while Executing Command', - description: DEBUG_MODE ? `\`\`\`D\n${stack}\`\`\`` : `\`\`\`\n${name}: ${message}\n\`\`\``, + description: IS_DEBUG_MODE ? `\`\`\`D\n${stack}\`\`\`` : `\`\`\`\n${name}: ${message}\n\`\`\``, }); await msg.channel.send({ embeds: [errorEmbed] }); @@ -130,7 +131,7 @@ for (const file of eventHandlers) { } } -client.login(process.env.DISCORD_TOKEN) +client.login(DISCORD_TOKEN) .then() .catch((e) => { Logger.error(e); diff --git a/src/lib/logger.ts b/src/lib/logger.ts index 3677fa2..4353f17 100644 --- a/src/lib/logger.ts +++ b/src/lib/logger.ts @@ -2,19 +2,20 @@ import winston from 'winston'; import ecsFormat from '@elastic/ecs-winston-format'; +import { DEBUG_MODE, NODE_ENV } from '../secrets'; const level = () => { - if (process.env.DEBUG_MODE === 'true') { + if (DEBUG_MODE === 'true') { return 'debug'; } - const env = process.env.NODE_ENV || 'development'; + const env = NODE_ENV || 'development'; const isDevelopment = env === 'development'; return isDevelopment ? 'debug' : 'info'; }; const format = () => { - const env = process.env.NODE_ENV || 'development'; + const env = NODE_ENV || 'development'; const isDevelopment = env === 'development'; return isDevelopment ? winston.format.simple() : ecsFormat(); }; diff --git a/src/secrets.ts b/src/secrets.ts new file mode 100644 index 0000000..e7dfe6e --- /dev/null +++ b/src/secrets.ts @@ -0,0 +1,19 @@ +const fs = require('fs'); + +// Function to read secrets from the file +function readSecret(secretPath) { + try { + return fs.readFileSync(secretPath, 'utf8').trim(); + } catch (err) { + console.error(`Error reading secret from ${secretPath}:`, err); + return null; + } +} + +// Read secrets from Docker secret files specified by environment variables +export const DEBUG_MODE = readSecret(process.env.DEBUG_MODE); +export const NODE_ENV = readSecret(process.env.NODE_ENV); +export const DISCORD_TOKEN = readSecret(process.env.DISCORD_TOKEN); +export const METAR_TOKEN = readSecret(process.env.METAR_TOKEN); +export const STATION_TOKEN = readSecret(process.env.STATION_TOKEN); +export const BAN_APPEAL_URL = readSecret(process.env.BAN_APPEAL_URL)