Compare commits

...

66 commits

Author SHA1 Message Date
7c06d07765 bwa
All checks were successful
Code quality checks / build (23) (push) Successful in 49s
Push code / build (push) Successful in 1m0s
2025-01-29 14:29:59 +00:00
de76af0a8a
clear cookie
All checks were successful
Code quality checks / build (23) (push) Successful in 35s
Push code / build (push) Successful in 53s
2024-11-03 13:30:07 +02:00
2a58b0698b
change button to link for logout
Some checks failed
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Failing after 2s
2024-11-03 13:25:55 +02:00
a967a298cb
logout functionality hopefully
Some checks failed
Code quality checks / build (23) (push) Successful in 35s
Push code / build (push) Has been cancelled
2024-11-03 13:23:33 +02:00
16651fce27
this is so cursed
All checks were successful
Code quality checks / build (23) (push) Successful in 33s
Push code / build (push) Successful in 52s
2024-11-03 12:51:58 +02:00
b4392ea66a
underline lol
All checks were successful
Code quality checks / build (23) (push) Successful in 35s
Push code / build (push) Successful in 54s
2024-11-03 12:45:09 +02:00
07a1b74b58
path messup lmao
All checks were successful
Code quality checks / build (23) (push) Successful in 35s
Push code / build (push) Successful in 54s
2024-11-03 12:05:32 +02:00
7afcfdc7aa
oops
All checks were successful
Code quality checks / build (23) (push) Successful in 33s
Push code / build (push) Successful in 54s
2024-11-03 12:03:42 +02:00
9f6cb8ba84
use more server crap, hopefully fix redir loop
All checks were successful
Code quality checks / build (23) (push) Successful in 33s
Push code / build (push) Successful in 53s
2024-11-03 11:59:26 +02:00
77dd220e48
don't cache in dashboard
All checks were successful
Code quality checks / build (23) (push) Successful in 35s
Push code / build (push) Successful in 54s
2024-11-03 11:42:12 +02:00
c1eff928be
hopefully fix login loop
All checks were successful
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Successful in 53s
2024-11-03 11:32:55 +02:00
cf28aed45a
error improvements 2024-11-03 11:31:53 +02:00
a4c4d48027
browser cache
All checks were successful
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Successful in 54s
2024-11-02 22:51:59 +02:00
f4c6690f1f
fix some redirect vulnerabilities
All checks were successful
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Successful in 52s
2024-11-02 22:46:23 +02:00
abea7b3e47
figure out why it's stuck in an infinite loop
All checks were successful
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Successful in 53s
2024-11-02 22:42:28 +02:00
e44510110b
login check
All checks were successful
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Successful in 53s
2024-11-02 22:36:28 +02:00
6a83355db1
hm
All checks were successful
Code quality checks / build (23) (push) Successful in 35s
Push code / build (push) Successful in 53s
2024-11-02 22:26:39 +02:00
2e5a76a102
use NextFunction
All checks were successful
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Successful in 52s
2024-11-02 22:12:27 +02:00
6bbcfd011e
oops again
All checks were successful
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Successful in 53s
2024-11-02 22:06:46 +02:00
0912f27668
oops
Some checks failed
Push code / build (push) Waiting to run
Code quality checks / build (23) (push) Has been cancelled
2024-11-02 22:06:32 +02:00
f0038acb61
login-callback
All checks were successful
Code quality checks / build (23) (push) Successful in 35s
Push code / build (push) Successful in 53s
2024-11-02 22:03:43 +02:00
ffb8dd5a23
cookie parser
All checks were successful
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Successful in 1m22s
2024-11-02 21:31:56 +02:00
996a6500ce
add support for new dashboard
All checks were successful
Code quality checks / build (23) (push) Successful in 35s
Push code / build (push) Successful in 53s
2024-11-02 21:17:37 +02:00
2f1dee7a91
placeholder page
All checks were successful
Code quality checks / build (23) (push) Successful in 35s
Push code / build (push) Successful in 53s
2024-11-02 20:46:26 +02:00
32a4b00333
dashboard layout
All checks were successful
Code quality checks / build (23) (push) Successful in 35s
Push code / build (push) Successful in 1m22s
2024-11-02 20:43:53 +02:00
4c8f925d94
meow
All checks were successful
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Successful in 1m20s
2024-11-02 20:29:00 +02:00
b52ac3409b
meow
All checks were successful
Code quality checks / build (23) (push) Successful in 35s
Push code / build (push) Successful in 50s
2024-11-02 19:32:37 +02:00
8f4d5eeef9
meow
All checks were successful
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Successful in 47s
2024-11-02 17:11:49 +02:00
1fcbbaab55
i went overboard
All checks were successful
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Successful in 45s
2024-11-02 17:07:25 +02:00
ca31bba520
use cryptographically secure random bytes instead of uuid
All checks were successful
Code quality checks / build (23) (push) Successful in 35s
Push code / build (push) Successful in 50s
2024-11-02 17:03:32 +02:00
536e0690ae
small eslint cleanups
All checks were successful
Code quality checks / build (23) (push) Successful in 35s
Push code / build (push) Successful in 46s
2024-11-02 16:50:57 +02:00
4e49e2d635
bruh
Some checks failed
Code quality checks / build (23) (push) Failing after 30s
Push code / build (push) Successful in 1m12s
2024-11-02 16:45:41 +02:00
5cebf53e04
i had a eureka moment and hopefully it works
Some checks failed
Code quality checks / build (23) (push) Failing after 23s
Push code / build (push) Successful in 1m12s
2024-11-02 16:39:00 +02:00
2b25a0106b
hm
All checks were successful
Code quality checks / build (23) (push) Successful in 35s
Push code / build (push) Successful in 47s
2024-11-02 16:31:23 +02:00
1e18419093
use request uri
Some checks failed
Code quality checks / build (23) (push) Has been cancelled
Push code / build (push) Successful in 1m12s
2024-11-02 16:25:16 +02:00
8f8c521242
oopsies
Some checks failed
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Failing after 3s
2024-11-02 16:19:36 +02:00
c2da2a8058
let's see if this works
Some checks failed
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Failing after 37s
2024-11-02 16:17:41 +02:00
88afb77abf
let's see if this works
All checks were successful
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Successful in 45s
2024-11-02 16:10:28 +02:00
dd8d3a2c88
just don't bother with catch all server_name
All checks were successful
Code quality checks / build (23) (push) Successful in 36s
Push code / build (push) Successful in 48s
2024-11-02 16:04:43 +02:00
1eebc56f51
oopsie
All checks were successful
Code quality checks / build (23) (push) Successful in 36s
Push code / build (push) Successful in 44s
2024-11-02 15:58:48 +02:00
1dea7721e5
was the presetup configuration even used, deploy new dashboard stuff
Some checks failed
Code quality checks / build (23) (push) Successful in 33s
Push code / build (push) Failing after 3s
2024-11-02 15:51:07 +02:00
f0ab9c6200 Update .github/workflows/codequality.yml
All checks were successful
Code quality checks / build (23) (push) Successful in 34s
Push code / build (push) Successful in 11s
Signed-off-by: laratheprotogen <laraproto@proton.me>
2024-11-02 13:22:51 +00:00
24b1ba0147 Update .github/workflows/codequality.yml
Some checks failed
Code quality checks / build (23) (push) Failing after 6s
Push code / build (push) Successful in 11s
2024-11-02 13:22:29 +00:00
8b6a1399a5 Update .github/workflows/codequality.yml
Some checks failed
Code quality checks / build (23) (push) Failing after 9s
Push code / build (push) Successful in 11s
2024-11-02 13:21:40 +00:00
38b1b71bbe Update .github/workflows/codequality.yml
Some checks failed
Code quality checks / build (latest) (push) Failing after 6s
Push code / build (push) Successful in 12s
2024-11-02 13:19:09 +00:00
bc456fbf17
bruh
Some checks failed
Code quality checks / build (18.16) (push) Failing after 4s
Push code / build (push) Successful in 1m5s
2024-11-02 15:06:12 +02:00
1e8a159c84
fix more npm references
Some checks failed
Code quality checks / build (18.16) (push) Failing after 4s
Push code / build (push) Failing after 1m5s
2024-11-02 15:03:16 +02:00
b2a9c2e0e7
wah
Some checks failed
Code quality checks / build (18.16) (push) Failing after 4s
Push code / build (push) Has been cancelled
2024-11-02 14:59:36 +02:00
10b8112ae8
wah
Some checks failed
Code quality checks / build (18.16) (push) Failing after 5s
Push code / build (push) Failing after 1m7s
2024-11-02 14:55:56 +02:00
09a573a2d3
the funny 2024-11-02 14:55:29 +02:00
5a555b7bb0 Update package.json
Some checks failed
Code quality checks / build (18.16) (push) Successful in 1m17s
Push code / build (push) Failing after 3s
2024-10-28 15:52:21 +00:00
7332960ea4 Update dashboard/src/components/PrivacyPolicy.vue
Some checks failed
Code quality checks / build (18.16) (push) Successful in 1m11s
Push code / build (push) Has been cancelled
2024-10-28 15:50:59 +00:00
81327f5c23 Update dashboard/src/splash.html
All checks were successful
Code quality checks / build (18.16) (push) Successful in 1m12s
Push code / build (push) Successful in 46s
2024-10-28 15:46:25 +00:00
5546ccda96 Update .github/workflows/push-code.yml
Some checks failed
Code quality checks / build (18.16) (push) Has been cancelled
Push code / build (push) Failing after 3s
2024-10-25 12:47:11 +00:00
e16e29cf50 add the ability to actually restart docker compose
Some checks failed
Code quality checks / build (18.16) (push) Successful in 1m13s
Push code / build (push) Failing after 6s
Signed-off-by: laratheprotogen <laraproto@proton.me>
2024-10-25 12:45:00 +00:00
3a5a1aca20 Update .github/workflows/push-code.yml
All checks were successful
Code quality checks / build (18.16) (push) Successful in 1m13s
Push code / build (push) Successful in 3s
2024-10-25 12:36:55 +00:00
46cdefbb21 Update .github/workflows/push-code.yml
Some checks failed
Code quality checks / build (18.16) (push) Has been cancelled
Push code / build (push) Successful in 3s
Signed-off-by: laratheprotogen <laraproto@proton.me>
2024-10-25 12:35:04 +00:00
2cc9844b8a Update .github/workflows/push-code.yml
Some checks failed
Code quality checks / build (18.16) (push) Has been cancelled
Signed-off-by: laratheprotogen <laraproto@proton.me>
2024-10-25 12:34:31 +00:00
0ff0115e3a Update .github/workflows/push-code.yml
Some checks failed
Code quality checks / build (18.16) (push) Has been cancelled
Push code / build (push) Failing after 1s
Signed-off-by: laratheprotogen <laraproto@proton.me>
2024-10-25 12:30:54 +00:00
12752504d1 Update .github/workflows/push-code.yml
Some checks failed
Code quality checks / build (18.16) (push) Has been cancelled
Push code / build (push) Failing after 2s
2024-10-25 12:29:22 +00:00
c149a08fc8 Update .github/workflows/push-code.yml
Some checks failed
Code quality checks / build (18.16) (push) Has been cancelled
Push code / build (push) Failing after 1s
Signed-off-by: laratheprotogen <laraproto@proton.me>
2024-10-25 12:28:25 +00:00
3f10d9d940 Add .github/workflows/push-code.yml
Some checks failed
Code quality checks / build (18.16) (push) Successful in 1m13s
Push code / build (push) Failing after 2s
Signed-off-by: laratheprotogen <laraproto@proton.me>
2024-10-25 12:08:47 +00:00
ZappyZep
b800fbe741 prettify
All checks were successful
Code quality checks / build (18.16) (push) Successful in 1m12s
2024-10-25 11:54:25 +00:00
43bbaa0035 Update .github/workflows/codequality.yml
Some checks failed
Code quality checks / build (18.16) (push) Failing after 1m21s
Signed-off-by: laratheprotogen <laraproto@proton.me>
2024-10-25 11:46:54 +00:00
ef75371c12 Update .github/workflows/codequality.yml
Some checks failed
Code quality checks / build (18.16) (push) Failing after 40s
2024-10-25 11:37:57 +00:00
ZappyZep
8c7a91dc80 meow
Some checks are pending
Code quality checks / build (18.16) (push) Waiting to run
2024-10-25 11:35:39 +00:00
187 changed files with 18648 additions and 25958 deletions

View file

@ -1,84 +0,0 @@
# ==========================
# GENERAL OPTIONS
# ==========================
# 32 character encryption key
KEY=
# Values from the Discord developer portal
CLIENT_ID=
CLIENT_SECRET=
BOT_TOKEN=
# The defaults here automatically work for the development environment.
# For production, change localhost:3300 to your domain.
DASHBOARD_URL=https://localhost:3300
API_URL=https://localhost:3300/api
# Comma-separated list of user IDs who should have access to the bot's global commands
STAFF=
# A comma-separated list of server IDs that should be allowed by default
DEFAULT_ALLOWED_SERVERS=
# Only required if relevant feature is used
#PHISHERMAN_API_KEY=
# ==========================
# DEVELOPMENT
# NOTE: You only need to fill in these values for running the development environment
# ==========================
DEVELOPMENT_WEB_PORT=3300
# The MySQL database running in the container is exposed to the host on this port,
# allowing access with database tools such as DBeaver
DEVELOPMENT_MYSQL_PORT=3356
# Password for the Zeppelin database user
DEVELOPMENT_MYSQL_PASSWORD=password
# Password for the MySQL root user
DEVELOPMENT_MYSQL_ROOT_PASSWORD=password
# The development environment container has an SSH server that you can connect to.
# This is the port that server is exposed to the host on.
DEVELOPMENT_SSH_PORT=3022
DEVELOPMENT_SSH_PASSWORD=password
# If your user has a different UID than 1000, you might have to fill that in here to avoid permission issues
#DEVELOPMENT_UID=1000
# ==========================
# PRODUCTION - STANDALONE
# NOTE: You only need to fill in these values for running the standalone production environment
# ==========================
STANDALONE_WEB_PORT=80
# The MySQL database running in the container is exposed to the host on this port,
# allowing access with database tools such as DBeaver
STANDALONE_MYSQL_PORT=3356
# Password for the Zeppelin database user
STANDALONE_MYSQL_PASSWORD=
# Password for the MySQL root user
STANDALONE_MYSQL_ROOT_PASSWORD=
# ==========================
# PRODUCTION - LIGHTWEIGHT
# NOTE: You only need to fill in these values for running the lightweight production environment
# ==========================
# Ports where the API/dashboard are exposed on the host
LIGHTWEIGHT_API_PORT=3001
LIGHTWEIGHT_DASHBOARD_PORT=3002
LIGHTWEIGHT_DB_HOST=
LIGHTWEIGHT_DB_PORT=
LIGHTWEIGHT_DB_USER=
LIGHTWEIGHT_DB_PASSWORD=
LIGHTWEIGHT_DB_DATABASE=
# If you want to add a prefix to API paths, such as /api, you can set that here
LIGHTWEIGHT_API_PATH_PREFIX=

View file

@ -1,28 +0,0 @@
module.exports = {
root: true,
env: {
node: true,
browser: true,
es6: true,
},
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint"],
rules: {
"@typescript-eslint/no-explicit-any": 0,
"@typescript-eslint/ban-ts-comment": 0,
"@typescript-eslint/no-non-null-assertion": 0,
"no-async-promise-executor": 0,
"@typescript-eslint/no-empty-interface": 0,
"no-constant-condition": ["error", {
checkLoops: false,
}],
"prefer-const": ["error", {
destructuring: "all",
ignoreReadBeforeAssign: true,
}],
"@typescript-eslint/no-namespace": ["error", {
allowDeclarations: true,
}],
},
};

View file

@ -8,16 +8,20 @@ jobs:
strategy:
matrix:
node-version: [18.16]
node-version: [23]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: npm install, lint, code style check
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: latest
- name: pnpm install, lint, code style check
run: |
npm ci
npm run lint
npm run codestyle-check
pnpm i
pnpm run lint
pnpm run codestyle-check

21
.github/workflows/push-code.yml vendored Normal file
View file

@ -0,0 +1,21 @@
name: Push code
on:
push:
branches:
- working-commit
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: install ssh keys
run: |
install -m 600 -D /dev/null ~/.ssh/id_ed25519
echo "${{ secrets.ZAPPYZEP_KEY }}" > ~/.ssh/id_ed25519
ssh-keyscan -H zappyzep.xyz > ~/.ssh/known_hosts
- name: connect and pull
run: ssh zappyzep@zappyzep.xyz "cd Zeppelin && git checkout working-commit && git pull && docker compose -f docker-compose.standalone.yml down && docker image rm zeppelin-prod-{api,dashboard,bot,migrate,nginx,revampdashboard} && docker compose -f docker-compose.standalone.yml up -d && exit"
- name: cleanup
run: rm -rf ~/.ssh

View file

@ -1,6 +1,7 @@
FROM node:20
RUN mkdir /zeppelin
RUN corepack enable
RUN chown node:node /zeppelin
USER node
@ -8,27 +9,34 @@ USER node
ARG API_URL
# Install dependencies before copying over any other files
COPY --chown=node:node package.json package-lock.json /zeppelin
RUN corepack prepare --activate pnpm@latest
COPY --chown=node:node package.json pnpm-lock.yaml pnpm-workspace.yaml /zeppelin/
RUN mkdir /zeppelin/backend
COPY --chown=node:node backend/package.json /zeppelin/backend
COPY --chown=node:node backend/package.json /zeppelin/backend/
RUN mkdir /zeppelin/shared
COPY --chown=node:node shared/package.json /zeppelin/shared
COPY --chown=node:node shared/package.json /zeppelin/shared/
RUN mkdir /zeppelin/dashboard
COPY --chown=node:node dashboard/package.json /zeppelin/dashboard
COPY --chown=node:node dashboard/package.json /zeppelin/dashboard/
RUN mkdir /zeppelin/revampdashboard
COPY --chown=node:node revampdashboard/package.json /zeppelin/revampdashboard/
WORKDIR /zeppelin
RUN npm ci
RUN pnpm i
COPY --chown=node:node . /zeppelin
# Build backend
WORKDIR /zeppelin/backend
RUN npm run build
RUN pnpm run build
# Build dashboard
WORKDIR /zeppelin/dashboard
RUN npm run build
RUN pnpm run build
WORKDIR /zeppelin/revampdashboard/
RUN pnpm run check
RUN pnpm run build
# Prune dev dependencies
WORKDIR /zeppelin
RUN npm prune --omit=dev
RUN pnpm prune --prod

View file

@ -18,26 +18,28 @@
"start-api-prod-debug": "clinic heapprofiler --collect-only --dest .clinic-api -- node --enable-source-maps --stack-trace-limit=30 dist/api/index.js",
"watch-api": "tsc-watch --build --onSuccess \"npm run start-api-dev\"",
"typeorm": "node ../node_modules/typeorm/cli.js",
"migrate": "npm run typeorm -- migration:run -d dist/data/dataSource.js",
"migrate-prod": "npm run migrate",
"migrate-dev": "npm run build && npm run migrate",
"migrate-rollback": "npm run typeorm -- migration:revert -d dist/data/dataSource.js",
"migrate-rollback-prod": "npm run migrate-rollback",
"migrate-rollback-dev": "npm run build && npm run migrate-rollback",
"migrate": "pnpm run typeorm -- migration:run -d dist/data/dataSource.js",
"migrate-prod": "pnpm run migrate",
"migrate-dev": "pnpm run build && npm run migrate",
"migrate-rollback": "pnpm run typeorm -- migration:revert -d dist/data/dataSource.js",
"migrate-rollback-prod": "pnpm run migrate-rollback",
"migrate-rollback-dev": "pnpm run build && npm run migrate-rollback",
"validate-active-configs": "node --enable-source-maps dist/validateActiveConfigs.js > ../config-errors.txt",
"export-config-json-schema": "node --enable-source-maps dist/exportSchemas.js > ../config-schema.json",
"test": "npm run build && npm run run-tests",
"test": "pnpm run build && pnpm run run-tests",
"run-tests": "ava",
"test-watch": "tsc-watch --build --onSuccess \"npx ava\""
},
"dependencies": {
"@silvia-odwyer/photon-node": "^0.3.1",
"@zeppelinbot/shared": "workspace:*",
"bufferutil": "^4.0.3",
"clinic": "^13.0.0",
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
"cross-env": "^7.0.3",
"deep-diff": "^1.0.2",
"discord.js": "^14.14.1",
"discord.js": "^14.16.3",
"dotenv": "^4.0.0",
"emoji-regex": "^8.0.0",
"escape-string-regexp": "^1.0.5",
@ -48,12 +50,14 @@
"knub": "^32.0.0-next.21",
"knub-command-manager": "^9.1.0",
"last-commit-log": "^2.1.0",
"lodash": "^4.17.21",
"lodash.chunk": "^4.2.0",
"lodash.clonedeep": "^4.5.0",
"lodash.difference": "^4.5.0",
"lodash.intersection": "^4.4.0",
"lodash.isequal": "^4.5.0",
"lodash.pick": "^4.4.0",
"moment": "^2.29.4",
"moment-timezone": "^0.5.21",
"multer": "^1.4.5-lts.1",
"mysql2": "^3.9.3",
@ -72,18 +76,20 @@
"tmp": "0.0.33",
"tsconfig-paths": "^3.9.0",
"twemoji": "^12.1.4",
"typeorm": "^0.3.17",
"typeorm": "^0.3.20",
"utf-8-validate": "^5.0.5",
"uuid": "^9.0.0",
"yawn-yaml": "github:dragory/yawn-yaml#string-number-fix-build",
"zlib-sync": "^0.1.7",
"zlib-sync": "^0.1.9",
"zod": "^3.7.2"
},
"devDependencies": {
"@types/cookie-parser": "^1.4.7",
"@types/cors": "^2.8.5",
"@types/express": "^4.16.1",
"@types/jest": "^24.0.15",
"@types/js-yaml": "^3.12.1",
"@types/lodash": "^4.17.13",
"@types/lodash.at": "^4.6.3",
"@types/moment-timezone": "^0.5.6",
"@types/multer": "^1.4.7",
@ -96,7 +102,7 @@
"@types/twemoji": "^12.1.0",
"@types/uuid": "^9.0.2",
"ava": "^5.3.1",
"rimraf": "^2.6.2",
"rimraf": "^6.0.1",
"source-map-support": "^0.5.16",
"zod-to-json-schema": "^3.22.3"
},

View file

@ -47,7 +47,7 @@ export class SimpleCache<T = any> {
if (this.maxItems && this.store.size > this.maxItems) {
const keyToDelete = this.store.keys().next().value;
this.store.delete(keyToDelete);
this.store.delete(keyToDelete!);
}
}

View file

@ -1,4 +1,4 @@
import express, { Request, Response } from "express";
import express, { NextFunction, Request, Response } from "express";
import https from "https";
import pick from "lodash.pick";
import passport from "passport";
@ -111,14 +111,32 @@ export function initAuth(router: express.Router) {
);
router.get("/auth/login", passport.authenticate("oauth2"));
router.get(
"/auth/new-login",
(req: Request, res: Response, next: NextFunction) => {
res.cookie("redir", `/new/auth/login-callback/`, { httpOnly: true });
next();
},
passport.authenticate("oauth2"),
);
router.get(
"/auth/oauth-callback",
passport.authenticate("oauth2", { failureRedirect: "/", session: false }),
(req: Request, res: Response) => {
res.clearCookie("redir");
if (req.user && req.user.apiKey) {
res.redirect(`${env.DASHBOARD_URL}/login-callback/?apiKey=${req.user.apiKey}`);
res.redirect(
req.cookies.redir
? `${env.DASHBOARD_URL}${req.cookies.redir.toString()}?apiKey=${req.user.apiKey}`
: `${env.DASHBOARD_URL}/login-callback/?apiKey=${req.user.apiKey}`,
);
} else {
res.redirect(`${env.DASHBOARD_URL}/login-callback/?error=noAccess`);
res.redirect(
req.cookies.redir
? `${env.DASHBOARD_URL}${req.cookies.redir.toString()}?error=noAccess`
: `${env.DASHBOARD_URL}/login-callback/?error=noAccess`,
);
}
},
);
@ -150,7 +168,6 @@ export function initAuth(router: express.Router) {
export function apiTokenAuthHandlers() {
return [
passport.authenticate("api-token", { failWithError: true, session: false }),
// eslint-disable-next-line @typescript-eslint/no-unused-vars
(err, req: Request, res: Response, next) => {
return res.status(401).json({ error: err.message });
},

View file

@ -1,6 +1,7 @@
import cors from "cors";
import express from "express";
import multer from "multer";
import cookieParser from "cookie-parser";
import { TokenError } from "passport-oauth2";
import { env } from "../env";
import { initArchives } from "./archives";
@ -25,13 +26,14 @@ app.use(
}),
);
app.use(multer().none());
app.use(cookieParser());
const rootRouter = express.Router();
initAuth(app);
initGuildsAPI(app);
initArchives(app);
initDocs(app);
initAuth(rootRouter);
initGuildsAPI(rootRouter);
initArchives(rootRouter);
initDocs(rootRouter);
// Default route
rootRouter.get("/", (req, res) => {

View file

@ -7,6 +7,7 @@ import { DAYS, DBDateFormat } from "../utils";
import { BaseRepository } from "./BaseRepository";
import { dataSource } from "./dataSource";
import { ApiLogin } from "./entities/ApiLogin";
import { randomBytes } from "node:crypto";
const LOGIN_EXPIRY_TIME = 1 * DAYS;
@ -48,7 +49,7 @@ export class ApiLogins extends BaseRepository {
// Generate random login id
let loginId;
while (true) {
loginId = uuidv4();
loginId = randomBytes(16).toString("hex");
const existing = await this.apiLogins.findOne({
where: {
id: loginId,
@ -58,7 +59,7 @@ export class ApiLogins extends BaseRepository {
}
// Generate token
const token = uuidv4();
const token = randomBytes(32).toString("hex");
const hash = crypto.createHash("sha256");
hash.update(loginId + token); // Use loginId as a salt
const hashedToken = hash.digest("hex");

View file

@ -3,7 +3,7 @@ import { Repository } from "typeorm";
import { DBDateFormat } from "../utils";
import { BaseRepository } from "./BaseRepository";
import { dataSource } from "./dataSource";
import { ApiUserInfoData, ApiUserInfo as ApiUserInfoEntity } from "./entities/ApiUserInfo";
import { ApiUserInfo as ApiUserInfoEntity, ApiUserInfoData } from "./entities/ApiUserInfo";
export class ApiUserInfo extends BaseRepository {
private apiUserInfo: Repository<ApiUserInfoEntity>;

View file

@ -1,7 +1,7 @@
import { Guild, Snowflake } from "discord.js";
import moment from "moment-timezone";
import { Repository } from "typeorm";
import { TemplateSafeValueContainer, renderTemplate } from "../templateFormatter";
import { renderTemplate, TemplateSafeValueContainer } from "../templateFormatter";
import { renderUsername, trimLines } from "../utils";
import { decrypt, encrypt } from "../utils/crypt";
import { isDefaultSticker } from "../utils/isDefaultSticker";

View file

@ -5,7 +5,7 @@ import { DAYS, DBDateFormat, HOURS, MINUTES } from "../utils";
import { BaseGuildRepository } from "./BaseGuildRepository";
import { dataSource } from "./dataSource";
import { Counter } from "./entities/Counter";
import { CounterTrigger, TriggerComparisonOp, isValidCounterComparisonOp } from "./entities/CounterTrigger";
import { CounterTrigger, isValidCounterComparisonOp, TriggerComparisonOp } from "./entities/CounterTrigger";
import { CounterTriggerState } from "./entities/CounterTriggerState";
import { CounterValue } from "./entities/CounterValue";

View file

@ -44,7 +44,7 @@ import { baseGuildPlugins, globalPlugins, guildPlugins } from "./plugins/availab
import { setProfiler } from "./profiler";
import { logRateLimit } from "./rateLimitStats";
import { startUptimeCounter } from "./uptime";
import { MINUTES, SECONDS, errorMessage, isDiscordAPIError, isDiscordHTTPError, sleep, successMessage } from "./utils";
import { errorMessage, isDiscordAPIError, isDiscordHTTPError, MINUTES, SECONDS, sleep, successMessage } from "./utils";
import { DecayingCounter } from "./utils/DecayingCounter";
import { enableProfiling } from "./utils/easyProfiler";
import { loadYamlSafely } from "./utils/loadYamlSafely";

View file

@ -3,18 +3,24 @@ import { MigrationInterface, QueryRunner, Table, TableColumn } from "typeorm";
export class MoveStarboardsToConfig1573248462469 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
// Create a new column for the channel's id
await queryRunner.addColumn("starboard_messages", new TableColumn({
name: "starboard_channel_id",
type: "bigint",
unsigned: true,
}));
await queryRunner.addColumn(
"starboard_messages",
new TableColumn({
name: "starboard_channel_id",
type: "bigint",
unsigned: true,
}),
);
// Since we are removing the guild_id with the starboards table, we might want it here
await queryRunner.addColumn("starboard_messages", new TableColumn({
name: "guild_id",
type: "bigint",
unsigned: true,
}));
await queryRunner.addColumn(
"starboard_messages",
new TableColumn({
name: "guild_id",
type: "bigint",
unsigned: true,
}),
);
// Migrate the old starboard_id to the new starboard_channel_id
await queryRunner.query(`
@ -43,11 +49,14 @@ export class MoveStarboardsToConfig1573248462469 implements MigrationInterface {
await queryRunner.dropColumn("starboard_messages", "starboard_channel_id");
await queryRunner.dropColumn("starboard_messages", "guild_id");
await queryRunner.addColumn("starboard_messages", new TableColumn({
name: "starboard_id",
type: "int",
unsigned: true,
}));
await queryRunner.addColumn(
"starboard_messages",
new TableColumn({
name: "starboard_id",
type: "int",
unsigned: true,
}),
);
await queryRunner.query(`
ALTER TABLE starboard_messages

View file

@ -3,12 +3,14 @@
*/
import {
DMChannel,
GuildMember,
Message,
MessageCreateOptions,
MessageMentionOptions,
PermissionsBitField,
TextBasedChannel,
TextChannel,
} from "discord.js";
import { AnyPluginData, BasePluginData, CommandContext, ExtendedMatchParams, GuildPluginData, helpers } from "knub";
import { logger } from "./logger";
@ -61,7 +63,7 @@ export async function sendSuccessMessage(
? { content: formattedBody, allowedMentions }
: { content: formattedBody };
return channel
return ((channel as TextChannel) || DMChannel)
.send({ ...content }) // Force line break
.catch((err) => {
const channelInfo = "guild" in channel ? `${channel.id} (${channel.guild.id})` : channel.id;
@ -82,7 +84,7 @@ export async function sendErrorMessage(
? { content: formattedBody, allowedMentions }
: { content: formattedBody };
return channel
return ((channel as TextChannel) || DMChannel)
.send({ ...content }) // Force line break
.catch((err) => {
const channelInfo = "guild" in channel ? `${channel.id} (${channel.guild.id})` : channel.id;

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { GuildLogs } from "../../data/GuildLogs";
import { GuildSavedMessages } from "../../data/GuildSavedMessages";
import { LogsPlugin } from "../Logs/LogsPlugin";

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { GuildAutoReactions } from "../../data/GuildAutoReactions";
import { GuildSavedMessages } from "../../data/GuildSavedMessages";
import { LogsPlugin } from "../Logs/LogsPlugin";

View file

@ -1,7 +1,7 @@
import { PermissionsBitField, PermissionsString } from "discord.js";
import { U } from "ts-toolbelt";
import z from "zod";
import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter";
import { renderTemplate, TemplateParseError, TemplateSafeValueContainer } from "../../../templateFormatter";
import { isValidSnowflake, keys, noop, zBoundedCharacters } from "../../../utils";
import {
guildToTemplateSafeGuild,

View file

@ -1,6 +1,6 @@
import { GuildTextBasedChannel, MessageCreateOptions, PermissionsBitField, Snowflake, User } from "discord.js";
import z from "zod";
import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter";
import { renderTemplate, TemplateParseError, TemplateSafeValueContainer } from "../../../templateFormatter";
import {
convertDelayStringToMS,
noop,

View file

@ -1,7 +1,7 @@
import { ChannelType, GuildTextThreadCreateOptions, ThreadAutoArchiveDuration, ThreadChannel } from "discord.js";
import z from "zod";
import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter";
import { MINUTES, convertDelayStringToMS, noop, zBoundedCharacters, zDelayString } from "../../../utils";
import { renderTemplate, TemplateParseError, TemplateSafeValueContainer } from "../../../templateFormatter";
import { convertDelayStringToMS, MINUTES, noop, zBoundedCharacters, zDelayString } from "../../../utils";
import { savedMessageToTemplateSafeSavedMessage, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { LogsPlugin } from "../../Logs/LogsPlugin";
import { automodAction } from "../helpers";

View file

@ -1,7 +1,7 @@
import { Snowflake } from "discord.js";
import { GuildPluginData } from "knub";
import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError";
import { UserNotificationMethod, disableUserNotificationStrings } from "../../../utils";
import { disableUserNotificationStrings, UserNotificationMethod } from "../../../utils";
import { AutomodPluginType } from "../types";
export function resolveActionContactMethods(

View file

@ -51,10 +51,10 @@ export const MatchInvitesTrigger = automodTrigger<MatchResultType>()({
const invite = await resolveInvite(pluginData.client, code);
if (!invite || !isGuildInvite(invite)) return { extra: { type, code } };
if (trigger.include_guilds && trigger.include_guilds.includes(invite.guild.id)) {
if (trigger.include_guilds && trigger.include_guilds.includes(await zSnowflake.parseAsync(invite.guild.id))) {
return { extra: { type, code, invite } };
}
if (trigger.exclude_guilds && !trigger.exclude_guilds.includes(invite.guild.id)) {
if (trigger.exclude_guilds && !trigger.exclude_guilds.includes(await zSnowflake.parseAsync(invite.guild.id))) {
return { extra: { type, code, invite } };
}
}

View file

@ -1,4 +1,4 @@
import { User, escapeBold, type Snowflake } from "discord.js";
import { escapeBold, type Snowflake, User } from "discord.js";
import z from "zod";
import { renderUsername } from "../../../utils";
import { automodTrigger } from "../helpers";

View file

@ -1,4 +1,4 @@
import { User, escapeBold, type Snowflake } from "discord.js";
import { escapeBold, type Snowflake, User } from "discord.js";
import z from "zod";
import { renderUsername } from "../../../utils.js";
import { automodTrigger } from "../helpers";

View file

@ -1,4 +1,4 @@
import { User, escapeBold, type Snowflake } from "discord.js";
import { escapeBold, type Snowflake, User } from "discord.js";
import z from "zod";
import { renderUsername } from "../../../utils.js";
import { automodTrigger } from "../helpers";

View file

@ -1,4 +1,4 @@
import { User, escapeBold, type Snowflake } from "discord.js";
import { escapeBold, type Snowflake, User } from "discord.js";
import z from "zod";
import { renderUsername } from "../../../utils";
import { automodTrigger } from "../helpers";

View file

@ -10,12 +10,11 @@ import { GuildSavedMessages } from "../../data/GuildSavedMessages";
import { SavedMessage } from "../../data/entities/SavedMessage";
import { entries, zBoundedRecord, zDelayString } from "../../utils";
import { CounterEvents } from "../Counters/types";
import { ModActionType, ModActionsEvents } from "../ModActions/types";
import { ModActionsEvents, ModActionType } from "../ModActions/types";
import { MutesEvents } from "../Mutes/types";
import { availableActions } from "./actions/availableActions";
import { RecentActionType } from "./constants";
import { availableTriggers } from "./triggers/availableTriggers";
import Timeout = NodeJS.Timeout;
export type ZTriggersMapHelper = {

View file

@ -1,6 +1,7 @@
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { isStaffPreFilter, sendErrorMessage } from "../../../pluginUtils";
import { botControlCmd } from "../types";
import { TextBasedChannelFields } from "discord.js";
export const ChannelToServerCmd = botControlCmd({
trigger: ["channel_to_server", "channel2server"],
@ -16,7 +17,7 @@ export const ChannelToServerCmd = botControlCmd({
async run({ pluginData, message: msg, args }) {
const channel = pluginData.client.channels.cache.get(args.channelId);
if (!channel) {
sendErrorMessage(pluginData, msg.channel, "Channel not found in cache!");
await sendErrorMessage(pluginData, msg.channel, "Channel not found in cache!");
return;
}
@ -25,6 +26,8 @@ export const ChannelToServerCmd = botControlCmd({
const guild = "guild" in channel ? channel.guild : null;
const guildInfo = guild ? `${guild.name} (\`${guild.id}\`)` : "Not a server";
msg.channel.send(`**Channel:** ${channelName} (\`${channel.type}\`) (<#${channel.id}>)\n**Server:** ${guildInfo}`);
await (msg.channel as TextBasedChannelFields).send(
`**Channel:** ${channelName} (\`${channel.type}\`) (<#${channel.id}>)\n**Server:** ${guildInfo}`,
);
},
});

View file

@ -4,6 +4,7 @@ import { GuildArchives } from "../../../data/GuildArchives";
import { getBaseUrl } from "../../../pluginUtils";
import { sorter } from "../../../utils";
import { botControlCmd } from "../types";
import { TextBasedChannelFields } from "discord.js";
const sortProps = {
totalTime: "TOTAL TIME",
@ -51,6 +52,6 @@ export const ProfilerDataCmd = botControlCmd({
const archiveId = await archives.create(formatted, moment().add(1, "hour"));
const archiveUrl = archives.getUrl(getBaseUrl(pluginData), archiveId);
msg.channel.send(`Link: ${archiveUrl}`);
await (msg.channel as TextBasedChannelFields).send(`Link: ${archiveUrl}`);
},
});

View file

@ -3,6 +3,7 @@ import { GuildArchives } from "../../../data/GuildArchives";
import { getBaseUrl, sendSuccessMessage } from "../../../pluginUtils";
import { getRateLimitStats } from "../../../rateLimitStats";
import { botControlCmd } from "../types";
import { TextBasedChannelFields } from "discord.js";
export const RateLimitPerformanceCmd = botControlCmd({
trigger: ["rate_limit_performance"],
@ -34,6 +35,6 @@ export const RateLimitPerformanceCmd = botControlCmd({
const archives = GuildArchives.getGuildInstance("0");
const archiveId = await archives.create(fullText, moment().add(1, "hour"));
const archiveUrl = archives.getUrl(getBaseUrl(pluginData), archiveId);
msg.channel.send(`Link: ${archiveUrl}`);
await (msg.channel as TextBasedChannelFields).send(`Link: ${archiveUrl}`);
},
});

View file

@ -1,6 +1,7 @@
import { isStaffPreFilter, sendErrorMessage } from "../../../pluginUtils";
import { getActiveReload, setActiveReload } from "../activeReload";
import { botControlCmd } from "../types";
import { TextBasedChannelFields } from "discord.js";
export const ReloadGlobalPluginsCmd = botControlCmd({
trigger: "bot_reload_global_plugins",
@ -14,13 +15,13 @@ export const ReloadGlobalPluginsCmd = botControlCmd({
const guildId = "guild" in message.channel ? message.channel.guild.id : null;
if (!guildId) {
sendErrorMessage(pluginData, message.channel, "This command can only be used in a server");
await sendErrorMessage(pluginData, message.channel, "This command can only be used in a server");
return;
}
setActiveReload(guildId, message.channel.id);
await message.channel.send("Reloading global plugins...");
await (message.channel as TextBasedChannelFields).send("Reloading global plugins...");
pluginData.getKnubInstance().reloadGlobalContext();
await pluginData.getKnubInstance().reloadGlobalContext();
},
});

View file

@ -2,6 +2,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes";
import { getTopRestCallStats } from "../../../restCallStats";
import { createChunkedMessage } from "../../../utils";
import { botControlCmd } from "../types";
import { TextChannel } from "discord.js";
const leadingPathRegex = /(?<=\().+\/backend\//g;
@ -20,6 +21,6 @@ export const RestPerformanceCmd = botControlCmd({
const cleanSource = callStats.source.replace(leadingPathRegex, "");
return `**${callStats.count} calls**\n${callStats.method.toUpperCase()} ${callStats.path}\n${cleanSource}`;
});
createChunkedMessage(msg.channel, `Top rest calls:\n\n${formatted.join("\n")}`);
await createChunkedMessage(msg.channel as TextChannel, `Top rest calls:\n\n${formatted.join("\n")}`);
},
});

View file

@ -3,6 +3,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes";
import { isStaffPreFilter } from "../../../pluginUtils";
import { createChunkedMessage, getUser, renderUsername, sorter } from "../../../utils";
import { botControlCmd } from "../types";
import { TextBasedChannelFields, TextChannel } from "discord.js";
export const ServersCmd = botControlCmd({
trigger: ["servers", "guilds"],
@ -52,16 +53,16 @@ export const ServersCmd = botControlCmd({
owner.id
}\`)`;
});
createChunkedMessage(msg.channel, lines.join("\n"));
await createChunkedMessage(msg.channel as TextChannel, lines.join("\n"));
} else {
msg.channel.send("No servers matched the filters");
await (msg.channel as TextBasedChannelFields).send("No servers matched the filters");
}
} else {
const total = joinedGuilds.length;
const initialized = joinedGuilds.filter((g) => loadedGuildsMap.has(g.id)).length;
const unInitialized = total - initialized;
msg.channel.send(
await (msg.channel as TextBasedChannelFields).send(
`I am on **${total} total servers**, of which **${initialized} are initialized** and **${unInitialized} are not initialized**`,
);
}

View file

@ -1,6 +1,6 @@
import { GuildPluginData } from "knub";
import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError";
import { UnknownUser, renderUsername, resolveUser } from "../../../utils";
import { renderUsername, resolveUser, UnknownUser } from "../../../utils";
import { CaseNoteArgs, CasesPluginType } from "../types";
import { postCaseToCaseLogChannel } from "./postToCaseLogChannel";
import { resolveCaseId } from "./resolveCaseId";

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { GuildLogs } from "../../data/GuildLogs";
import { GuildSavedMessages } from "../../data/GuildSavedMessages";
import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners";

View file

@ -5,7 +5,14 @@ import cloneDeep from "lodash.clonedeep";
import { allowTimeout } from "../../../RegExpRunner";
import { ZalgoRegex } from "../../../data/Zalgo";
import { SavedMessage } from "../../../data/entities/SavedMessage";
import { getInviteCodesInString, getUrlsInString, isGuildInvite, resolveInvite, resolveMember } from "../../../utils";
import {
getInviteCodesInString,
getUrlsInString,
isGuildInvite,
resolveInvite,
resolveMember,
zSnowflake,
} from "../../../utils";
import { CensorPluginType } from "../types";
import { censorMessage } from "./censorMessage";
@ -58,18 +65,18 @@ export async function applyFiltersToMsg(
for (const invite of invites) {
// Always filter unknown invites if invite filtering is enabled
if (invite == null) {
censorMessage(pluginData, savedMessage, `unknown invite not found in whitelist`);
await censorMessage(pluginData, savedMessage, `unknown invite not found in whitelist`);
return true;
}
if (!isGuildInvite(invite) && !allowGroupDMInvites) {
censorMessage(pluginData, savedMessage, `group dm invites are not allowed`);
await censorMessage(pluginData, savedMessage, `group dm invites are not allowed`);
return true;
}
if (isGuildInvite(invite)) {
if (inviteGuildWhitelist && !inviteGuildWhitelist.includes(invite.guild!.id)) {
censorMessage(
if (inviteGuildWhitelist && !inviteGuildWhitelist.includes(await zSnowflake.parseAsync(invite.guild!.id))) {
await censorMessage(
pluginData,
savedMessage,
`invite guild (**${invite.guild!.name}** \`${invite.guild!.id}\`) not found in whitelist`,
@ -77,8 +84,8 @@ export async function applyFiltersToMsg(
return true;
}
if (inviteGuildBlacklist && inviteGuildBlacklist.includes(invite.guild!.id)) {
censorMessage(
if (inviteGuildBlacklist && inviteGuildBlacklist.includes(await zSnowflake.parseAsync(invite.guild!.id))) {
await censorMessage(
pluginData,
savedMessage,
`invite guild (**${invite.guild!.name}** \`${invite.guild!.id}\`) found in blacklist`,

View file

@ -2,7 +2,7 @@ import { Snowflake } from "discord.js";
import moment from "moment-timezone";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { isOwner, sendErrorMessage } from "../../../pluginUtils";
import { SECONDS, confirm, noop, renderUsername } from "../../../utils";
import { confirm, noop, renderUsername, SECONDS } from "../../../utils";
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
import { rehostAttachment } from "../rehostAttachment";
import { channelArchiverCmd } from "../types";

View file

@ -1,6 +1,7 @@
import { Attachment, GuildTextBasedChannel, MessageCreateOptions } from "discord.js";
import fs from "fs";
import { downloadFile } from "../../utils";
const fsp = fs.promises;
const MAX_ATTACHMENT_REHOST_SIZE = 1024 * 1024 * 8;

View file

@ -1,6 +1,7 @@
import { StageChannel, VoiceChannel } from "discord.js";
import { GuildPluginData } from "knub";
import { CompanionChannelsPluginType, TCompanionChannelOpts } from "../types";
import { zSnowflake } from "../../../utils";
const defaultCompanionChannelOpts: Partial<TCompanionChannelOpts> = {
enabled: true,
@ -15,8 +16,8 @@ export async function getCompanionChannelOptsForVoiceChannelId(
return Object.values(config.entries)
.filter(
(opts) =>
opts.voice_channel_ids.includes(voiceChannel.id) ||
(voiceChannel.parentId && opts.voice_channel_ids.includes(voiceChannel.parentId)),
opts.voice_channel_ids.includes(zSnowflake.parse(voiceChannel.id)) ||
(voiceChannel.parentId && opts.voice_channel_ids.includes(zSnowflake.parse(voiceChannel.parentId))),
)
.map((opts) => Object.assign({}, defaultCompanionChannelOpts, opts));
}

View file

@ -1,7 +1,7 @@
import { PermissionsBitField, Snowflake, StageChannel, TextChannel, VoiceChannel } from "discord.js";
import { GuildPluginData } from "knub";
import { LogType } from "../../../data/LogType";
import { MINUTES, isDiscordAPIError } from "../../../utils";
import { isDiscordAPIError, MINUTES } from "../../../utils";
import { filterObject } from "../../../utils/filterObject";
import { LogsPlugin } from "../../Logs/LogsPlugin";
import { CompanionChannelsPluginType, TCompanionChannelOpts } from "../types";

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { GuildContextMenuLinks } from "../../data/GuildContextMenuLinks";
import { LogsPlugin } from "../Logs/LogsPlugin";
import { MutesPlugin } from "../Mutes/MutesPlugin";

View file

@ -1,9 +1,8 @@
import { EventEmitter } from "events";
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { GuildCounters } from "../../data/GuildCounters";
import { CounterTrigger, parseCounterConditionString } from "../../data/entities/CounterTrigger";
import { makePublicFn } from "../../pluginUtils";
import { MINUTES, convertDelayStringToMS, values } from "../../utils";
import { convertDelayStringToMS, MINUTES, values } from "../../utils";
import { AddCounterCmd } from "./commands/AddCounterCmd";
import { CountersListCmd } from "./commands/CountersListCmd";
import { ResetAllCounterValuesCmd } from "./commands/ResetAllCounterValuesCmd";
@ -19,6 +18,7 @@ import { offCounterEvent } from "./functions/offCounterEvent";
import { onCounterEvent } from "./functions/onCounterEvent";
import { setCounterValue } from "./functions/setCounterValue";
import { CountersPluginType, zCountersConfig } from "./types";
import { EventEmitter } from "events";
const DECAY_APPLY_INTERVAL = 5 * MINUTES;

View file

@ -3,7 +3,7 @@ import { guildPluginMessageCommand } from "knub";
import { waitForReply } from "knub/helpers";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sendErrorMessage } from "../../../pluginUtils";
import { UnknownUser, resolveUser } from "../../../utils";
import { resolveUser, UnknownUser } from "../../../utils";
import { changeCounterValue } from "../functions/changeCounterValue";
import { CountersPluginType } from "../types";

View file

@ -3,7 +3,7 @@ import { guildPluginMessageCommand } from "knub";
import { waitForReply } from "knub/helpers";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sendErrorMessage } from "../../../pluginUtils";
import { UnknownUser, resolveUser } from "../../../utils";
import { resolveUser, UnknownUser } from "../../../utils";
import { setCounterValue } from "../functions/setCounterValue";
import { CountersPluginType } from "../types";

View file

@ -3,7 +3,7 @@ import { guildPluginMessageCommand } from "knub";
import { waitForReply } from "knub/helpers";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sendErrorMessage } from "../../../pluginUtils";
import { UnknownUser, resolveUser } from "../../../utils";
import { resolveUser, UnknownUser } from "../../../utils";
import { setCounterValue } from "../functions/setCounterValue";
import { CountersPluginType } from "../types";

View file

@ -3,8 +3,8 @@ import { BasePluginType } from "knub";
import z from "zod";
import { GuildCounters, MAX_COUNTER_VALUE, MIN_COUNTER_VALUE } from "../../data/GuildCounters";
import {
CounterTrigger,
buildCounterConditionString,
CounterTrigger,
getReverseCounterComparisonOp,
parseCounterConditionString,
} from "../../data/entities/CounterTrigger";

View file

@ -2,7 +2,7 @@ import { GuildChannel, GuildMember, User } from "discord.js";
import { guildPlugin, guildPluginMessageCommand, parseSignature } from "knub";
import { TSignature } from "knub-command-manager";
import { commandTypes } from "../../commandTypes";
import { TemplateSafeValueContainer, createTypedTemplateSafeValueContainer } from "../../templateFormatter";
import { createTypedTemplateSafeValueContainer, TemplateSafeValueContainer } from "../../templateFormatter";
import { UnknownUser } from "../../utils";
import { isScalar } from "../../utils/isScalar";
import {

View file

@ -1,7 +1,7 @@
import { Snowflake, TextChannel } from "discord.js";
import { GuildPluginData } from "knub";
import z from "zod";
import { TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter";
import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter";
import { zBoundedCharacters, zSnowflake } from "../../../utils";
import { ActionError } from "../ActionError";
import { catchTemplateError } from "../catchTemplateError";

View file

@ -2,7 +2,7 @@ import { Snowflake, VoiceChannel } from "discord.js";
import { GuildPluginData } from "knub";
import z from "zod";
import { canActOn } from "../../../pluginUtils";
import { TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter";
import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter";
import { resolveMember, zSnowflake } from "../../../utils";
import { ActionError } from "../ActionError";
import { catchTemplateError } from "../catchTemplateError";

View file

@ -1,5 +1,5 @@
import { Guild } from "discord.js";
import { BasePluginType, GlobalPluginData, globalPlugin, globalPluginEventListener } from "knub";
import { BasePluginType, globalPlugin, GlobalPluginData, globalPluginEventListener } from "knub";
import z from "zod";
import { AllowedGuilds } from "../../data/AllowedGuilds";
import { Configs } from "../../data/Configs";

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import z from "zod";
import { Queue } from "../../Queue";
import { Webhooks } from "../../data/Webhooks";

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { onGuildEvent } from "../../data/GuildEvents";
import { GuildVCAlerts } from "../../data/GuildVCAlerts";
import { FollowCmd } from "./commands/FollowCmd";

View file

@ -3,6 +3,7 @@ import { clearExpiringVCAlert } from "../../../data/loops/expiringVCAlertsLoop";
import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
import { createChunkedMessage, sorter } from "../../../utils";
import { locateUserCmd } from "../types";
import { TextChannel } from "discord.js";
export const ListFollowCmd = locateUserCmd({
trigger: ["follows", "fs"],
@ -13,7 +14,7 @@ export const ListFollowCmd = locateUserCmd({
async run({ message: msg, pluginData }) {
const alerts = await pluginData.state.alerts.getAlertsByRequestorId(msg.member.id);
if (alerts.length === 0) {
sendErrorMessage(pluginData, msg.channel, "You have no active alerts!");
await sendErrorMessage(pluginData, msg.channel, "You have no active alerts!");
return;
}
@ -26,7 +27,7 @@ export const ListFollowCmd = locateUserCmd({
alert.body
}\` **Active:** ${alert.active.valueOf()}`;
});
await createChunkedMessage(msg.channel, lines.join("\n"));
await createChunkedMessage(msg.channel as TextChannel, lines.join("\n"));
},
});

View file

@ -1,4 +1,4 @@
import { CooldownManager, PluginOptions, guildPlugin } from "knub";
import { CooldownManager, guildPlugin, PluginOptions } from "knub";
import DefaultLogMessages from "../../data/DefaultLogMessages.json";
import { GuildArchives } from "../../data/GuildArchives";
import { GuildCases } from "../../data/GuildCases";

View file

@ -3,7 +3,7 @@ import { GuildPluginData } from "knub";
import { allowTimeout } from "../../../RegExpRunner";
import { LogType } from "../../../data/LogType";
import { TypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { MINUTES, isDiscordAPIError } from "../../../utils";
import { isDiscordAPIError, MINUTES, zSnowflake } from "../../../utils";
import { MessageBuffer } from "../../../utils/MessageBuffer";
import { InternalPosterPlugin } from "../../InternalPoster/InternalPosterPlugin";
import { ILogTypeData, LogsPluginType, TLogChannel, TLogChannelMap } from "../types";
@ -28,7 +28,11 @@ async function shouldExclude(
opts: TLogChannel,
exclusionData: ExclusionData,
): Promise<boolean> {
if (opts.excluded_users && exclusionData.userId && opts.excluded_users.includes(exclusionData.userId)) {
if (
opts.excluded_users &&
exclusionData.userId &&
opts.excluded_users.includes(zSnowflake.parse(exclusionData.userId))
) {
return true;
}
@ -38,21 +42,33 @@ async function shouldExclude(
if (opts.excluded_roles && exclusionData.roles) {
for (const role of exclusionData.roles) {
if (opts.excluded_roles.includes(role)) {
if (opts.excluded_roles.includes(await zSnowflake.parseAsync(role))) {
return true;
}
}
}
if (opts.excluded_channels && exclusionData.channel && opts.excluded_channels.includes(exclusionData.channel)) {
if (
opts.excluded_channels &&
exclusionData.channel &&
opts.excluded_channels.includes(await zSnowflake.parseAsync(exclusionData.channel))
) {
return true;
}
if (opts.excluded_categories && exclusionData.category && opts.excluded_categories.includes(exclusionData.category)) {
if (
opts.excluded_categories &&
exclusionData.category &&
opts.excluded_categories.includes(await zSnowflake.parseAsync(exclusionData.category))
) {
return true;
}
if (opts.excluded_threads && exclusionData.thread && opts.excluded_threads.includes(exclusionData.thread)) {
if (
opts.excluded_threads &&
exclusionData.thread &&
opts.excluded_threads.includes(await zSnowflake.parseAsync(exclusionData.thread))
) {
return true;
}
@ -83,20 +99,20 @@ export async function log<TLogType extends keyof ILogTypeData>(
const channel = pluginData.guild.channels.cache.get(channelId as Snowflake);
if (!channel?.isTextBased()) continue;
if (pluginData.state.channelCooldowns.isOnCooldown(channelId)) continue;
if (opts.include?.length && !opts.include.includes(typeStr)) continue;
if (opts.exclude && opts.exclude.includes(typeStr)) continue;
if (await shouldExclude(pluginData, opts, exclusionData)) continue;
if (opts!.include?.length && !opts!.include.includes(typeStr)) continue;
if (opts!.exclude && opts!.exclude.includes(typeStr)) continue;
if (await shouldExclude(pluginData, opts!, exclusionData)) continue;
const message = await getLogMessage(pluginData, type, data, {
format: opts.format,
include_embed_timestamp: opts.include_embed_timestamp,
timestamp_format: opts.timestamp_format,
format: opts!.format,
include_embed_timestamp: opts!.include_embed_timestamp,
timestamp_format: opts!.timestamp_format,
});
if (!message) return;
// Initialize message buffer for this channel
if (!pluginData.state.buffers.has(channelId)) {
const batchTime = Math.min(Math.max(opts.batch_time ?? DEFAULT_BATCH_TIME, MIN_BATCH_TIME), MAX_BATCH_TIME);
const batchTime = Math.min(Math.max(opts!.batch_time ?? DEFAULT_BATCH_TIME, MIN_BATCH_TIME), MAX_BATCH_TIME);
const internalPosterPlugin = pluginData.getPlugin(InternalPosterPlugin);
pluginData.state.buffers.set(
channelId,

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { GuildSavedMessages } from "../../data/GuildSavedMessages";
import { SaveMessagesToDBCmd } from "./commands/SaveMessagesToDB";
import { SavePinsToDBCmd } from "./commands/SavePinsToDB";

View file

@ -1,5 +1,4 @@
import { Message } from "discord.js";
import { EventEmitter } from "events";
import { guildPlugin } from "knub";
import { Queue } from "../../Queue";
import { GuildCases } from "../../data/GuildCases";
@ -48,6 +47,7 @@ import { onModActionsEvent } from "./functions/onModActionsEvent";
import { updateCase } from "./functions/updateCase";
import { warnMember } from "./functions/warnMember";
import { ModActionsPluginType, zModActionsConfig } from "./types";
import { EventEmitter } from "events";
const defaultOptions = {
config: {

View file

@ -1,7 +1,7 @@
import { APIEmbed } from "discord.js";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sendErrorMessage } from "../../../pluginUtils";
import { UnknownUser, emptyEmbedValue, renderUsername, resolveMember, resolveUser, trimLines } from "../../../utils";
import { emptyEmbedValue, renderUsername, resolveMember, resolveUser, trimLines, UnknownUser } from "../../../utils";
import { asyncMap } from "../../../utils/async";
import { createPaginatedMessage } from "../../../utils/createPaginatedMessage";
import { getGuildPrefix } from "../../../utils/getGuildPrefix";

View file

@ -3,7 +3,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes";
import { CaseTypes } from "../../../data/CaseTypes";
import { sendErrorMessage } from "../../../pluginUtils";
import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin";
import { UnknownUser, chunkArray, emptyEmbedValue, renderUsername, resolveMember, resolveUser } from "../../../utils";
import { chunkArray, emptyEmbedValue, renderUsername, resolveMember, resolveUser, UnknownUser } from "../../../utils";
import { asyncMap } from "../../../utils/async";
import { createPaginatedMessage } from "../../../utils/createPaginatedMessage.js";
import { getGuildPrefix } from "../../../utils/getGuildPrefix";

View file

@ -2,7 +2,7 @@ import { helpers } from "knub";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { Case } from "../../../data/entities/Case";
import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
import { SECONDS, renderUsername, trimLines } from "../../../utils";
import { renderUsername, SECONDS, trimLines } from "../../../utils";
import { CasesPlugin } from "../../Cases/CasesPlugin";
import { LogsPlugin } from "../../Logs/LogsPlugin";
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";

View file

@ -7,7 +7,7 @@ import { LogType } from "../../../data/LogType";
import { humanizeDurationShort } from "../../../humanizeDurationShort";
import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin";
import { DAYS, MINUTES, SECONDS, noop } from "../../../utils";
import { DAYS, MINUTES, noop, SECONDS } from "../../../utils";
import { LogsPlugin } from "../../Logs/LogsPlugin";
import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments";
import { ignoreEvent } from "../functions/ignoreEvent";

View file

@ -1,7 +1,7 @@
import { AuditLogEvent, User } from "discord.js";
import { CaseTypes } from "../../../data/CaseTypes";
import { Case } from "../../../data/entities/Case";
import { UnknownUser, resolveUser } from "../../../utils";
import { resolveUser, UnknownUser } from "../../../utils";
import { findMatchingAuditLogEntry } from "../../../utils/findMatchingAuditLogEntry";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { CasesPlugin } from "../../Cases/CasesPlugin";

View file

@ -2,7 +2,7 @@ import { AuditLogEvent, User } from "discord.js";
import { CaseTypes } from "../../../data/CaseTypes";
import { Case } from "../../../data/entities/Case";
import { logger } from "../../../logger";
import { UnknownUser, resolveUser } from "../../../utils";
import { resolveUser, UnknownUser } from "../../../utils";
import { findMatchingAuditLogEntry } from "../../../utils/findMatchingAuditLogEntry";
import { CasesPlugin } from "../../Cases/CasesPlugin";
import { LogsPlugin } from "../../Logs/LogsPlugin";

View file

@ -1,7 +1,7 @@
import { AuditLogEvent, User } from "discord.js";
import { CaseTypes } from "../../../data/CaseTypes";
import { Case } from "../../../data/entities/Case";
import { UnknownUser, resolveUser } from "../../../utils";
import { resolveUser, UnknownUser } from "../../../utils";
import { findMatchingAuditLogEntry } from "../../../utils/findMatchingAuditLogEntry";
import { CasesPlugin } from "../../Cases/CasesPlugin";
import { LogsPlugin } from "../../Logs/LogsPlugin";

View file

@ -3,7 +3,7 @@ import { GuildPluginData } from "knub";
import { hasPermission } from "knub/helpers";
import { LogType } from "../../../data/LogType";
import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
import { DAYS, SECONDS, errorMessage, renderUsername, resolveMember, resolveUser } from "../../../utils";
import { DAYS, errorMessage, renderUsername, resolveMember, resolveUser, SECONDS } from "../../../utils";
import { IgnoredEventType, ModActionsPluginType } from "../types";
import { formatReasonWithAttachments } from "./formatReasonWithAttachments";
import { ignoreEvent } from "./ignoreEvent";

View file

@ -4,7 +4,7 @@ import { GuildPluginData } from "knub";
import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError";
import { logger } from "../../../logger";
import { hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
import { UnknownUser, asSingleLine, isDiscordAPIError, renderUsername } from "../../../utils";
import { asSingleLine, isDiscordAPIError, renderUsername, UnknownUser } from "../../../utils";
import { MutesPlugin } from "../../Mutes/MutesPlugin";
import { MuteResult } from "../../Mutes/types";
import { ModActionsPluginType } from "../types";

View file

@ -3,7 +3,7 @@ import humanizeDuration from "humanize-duration";
import { GuildPluginData } from "knub";
import { hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin";
import { UnknownUser, asSingleLine, renderUsername } from "../../../utils";
import { asSingleLine, renderUsername, UnknownUser } from "../../../utils";
import { ModActionsPluginType } from "../types";
import { formatReasonWithAttachments } from "./formatReasonWithAttachments";

View file

@ -5,16 +5,16 @@ import { CaseTypes } from "../../../data/CaseTypes";
import { LogType } from "../../../data/LogType";
import { registerExpiringTempban } from "../../../data/loops/expiringTempbansLoop";
import { logger } from "../../../logger";
import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter";
import { renderTemplate, TemplateParseError, TemplateSafeValueContainer } from "../../../templateFormatter";
import {
DAYS,
SECONDS,
UserNotificationResult,
createUserNotificationError,
DAYS,
notifyUser,
resolveMember,
resolveUser,
SECONDS,
ucfirst,
UserNotificationResult,
} from "../../../utils";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { CasesPlugin } from "../../Cases/CasesPlugin";

View file

@ -1,6 +1,6 @@
import { PermissionsBitField, Snowflake } from "discord.js";
import { GuildPluginData } from "knub";
import { SECONDS, isDiscordAPIError, isDiscordHTTPError, sleep } from "../../../utils";
import { isDiscordAPIError, isDiscordHTTPError, SECONDS, sleep } from "../../../utils";
import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions";
import { LogsPlugin } from "../../Logs/LogsPlugin";
import { ModActionsPluginType } from "../types";

View file

@ -1,8 +1,8 @@
import { GuildMember, Snowflake } from "discord.js";
import { GuildPluginData } from "knub";
import { CaseTypes } from "../../../data/CaseTypes";
import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter";
import { UserNotificationResult, createUserNotificationError, notifyUser, resolveUser, ucfirst } from "../../../utils";
import { renderTemplate, TemplateParseError, TemplateSafeValueContainer } from "../../../templateFormatter";
import { createUserNotificationError, notifyUser, resolveUser, ucfirst, UserNotificationResult } from "../../../utils";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { waitForButtonConfirm } from "../../../utils/waitForInteraction";
import { CasesPlugin } from "../../Cases/CasesPlugin";

View file

@ -1,5 +1,4 @@
import { GuildMember, Snowflake } from "discord.js";
import { EventEmitter } from "events";
import { guildPlugin } from "knub";
import { GuildArchives } from "../../data/GuildArchives";
import { GuildCases } from "../../data/GuildCases";
@ -24,6 +23,7 @@ import { onMutesEvent } from "./functions/onMutesEvent";
import { renewTimeoutMute } from "./functions/renewTimeoutMute";
import { unmuteUser } from "./functions/unmuteUser";
import { MutesPluginType, zMutesConfig } from "./types";
import { EventEmitter } from "events";
const defaultOptions = {
config: {

View file

@ -9,15 +9,15 @@ import { Case } from "../../../data/entities/Case";
import { Mute } from "../../../data/entities/Mute";
import { registerExpiringMute } from "../../../data/loops/expiringMutesLoop";
import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin";
import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter";
import { renderTemplate, TemplateParseError, TemplateSafeValueContainer } from "../../../templateFormatter";
import {
UserNotificationMethod,
UserNotificationResult,
noop,
notifyUser,
resolveMember,
resolveUser,
ucfirst,
UserNotificationMethod,
UserNotificationResult,
} from "../../../utils";
import { muteLock } from "../../../utils/lockNameHelpers";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { Queue } from "../../Queue";
import { GuildNicknameHistory } from "../../data/GuildNicknameHistory";
import { UsernameHistory } from "../../data/UsernameHistory";

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { GuildLogs } from "../../data/GuildLogs";
import { GuildPersistedData } from "../../data/GuildPersistedData";
import { LogsPlugin } from "../Logs/LogsPlugin";

View file

@ -8,7 +8,7 @@ import { getMissingPermissions } from "../../../utils/getMissingPermissions";
import { missingPermissionError } from "../../../utils/missingPermissionError";
import { LogsPlugin } from "../../Logs/LogsPlugin";
import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin";
import { PersistPluginType, persistEvt } from "../types";
import { persistEvt, PersistPluginType } from "../types";
const p = PermissionFlagsBits;

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { hasPhishermanMasterAPIKey, phishermanApiKeyIsValid } from "../../data/Phisherman";
import { makePublicFn } from "../../pluginUtils";
import { getDomainInfo } from "./functions/getDomainInfo";

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { GuildPingableRoles } from "../../data/GuildPingableRoles";
import { PingableRoleDisableCmd } from "./commands/PingableRoleDisableCmd";
import { PingableRoleEnableCmd } from "./commands/PingableRoleEnableCmd";

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { onGuildEvent } from "../../data/GuildEvents";
import { GuildLogs } from "../../data/GuildLogs";
import { GuildSavedMessages } from "../../data/GuildSavedMessages";

View file

@ -1,4 +1,4 @@
import { escapeCodeBlock } from "discord.js";
import { escapeCodeBlock, TextChannel } from "discord.js";
import humanizeDuration from "humanize-duration";
import moment from "moment-timezone";
import { createChunkedMessage, DBDateFormat, deactivateMentions, sorter, trimLines } from "../../../utils";
@ -58,6 +58,6 @@ export const ScheduledPostsListCmd = postCmd({
Use \`scheduled_posts <num>\` to view a scheduled post in full
Use \`scheduled_posts delete <num>\` to delete a scheduled post
`);
createChunkedMessage(msg.channel, finalMessage);
createChunkedMessage(msg.channel as TextChannel, finalMessage);
},
});

View file

@ -1,10 +1,10 @@
import { GuildTextBasedChannel, Message } from "discord.js";
import { GuildTextBasedChannel, Message, TextBasedChannelFields } from "discord.js";
import humanizeDuration from "humanize-duration";
import { GuildPluginData } from "knub";
import moment from "moment-timezone";
import { registerUpcomingScheduledPost } from "../../../data/loops/upcomingScheduledPostsLoop";
import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
import { DBDateFormat, MINUTES, StrictMessageContent, errorMessage, renderUsername } from "../../../utils";
import { DBDateFormat, errorMessage, MINUTES, renderUsername, StrictMessageContent } from "../../../utils";
import { LogsPlugin } from "../../Logs/LogsPlugin";
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
import { PostPluginType } from "../types";
@ -29,12 +29,12 @@ export async function actualPostCmd(
} = {},
) {
if (!targetChannel.isTextBased()) {
msg.channel.send(errorMessage("Specified channel is not a text-based channel"));
await (msg.channel as TextBasedChannelFields).send(errorMessage("Specified channel is not a text-based channel"));
return;
}
if (content == null && msg.attachments.size === 0) {
msg.channel.send(errorMessage("Message content or attachment required"));
await (msg.channel as TextBasedChannelFields).send(errorMessage("Message content or attachment required"));
return;
}

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { Queue } from "../../Queue";
import { GuildReactionRoles } from "../../data/GuildReactionRoles";
import { GuildSavedMessages } from "../../data/GuildSavedMessages";

View file

@ -3,7 +3,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
import { canUseEmoji, isDiscordAPIError, isValidEmoji, noop, trimPluginDescription } from "../../../utils";
import { canReadChannel } from "../../../utils/canReadChannel";
import { TReactionRolePair, reactionRolesCmd } from "../types";
import { reactionRolesCmd, TReactionRolePair } from "../types";
import { applyReactionRoleReactionsToMessage } from "../util/applyReactionRoleReactionsToMessage";
const CLEAR_ROLES_EMOJI = "❌";

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { onGuildEvent } from "../../data/GuildEvents";
import { GuildReminders } from "../../data/GuildReminders";
import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin";

View file

@ -4,6 +4,7 @@ import { sendErrorMessage } from "../../../pluginUtils";
import { createChunkedMessage, DBDateFormat, sorter } from "../../../utils";
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
import { remindersCmd } from "../types";
import { TextChannel } from "discord.js";
export const RemindersCmd = remindersCmd({
trigger: "reminders",
@ -32,6 +33,6 @@ export const RemindersCmd = remindersCmd({
return `\`${paddedNum}.\` \`${prettyRemindAt} (${result})\` ${reminder.body}`;
});
createChunkedMessage(msg.channel, lines.join("\n"));
await createChunkedMessage(msg.channel as TextChannel, lines.join("\n"));
},
});

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { GuildLogs } from "../../data/GuildLogs";
import { LogsPlugin } from "../Logs/LogsPlugin";
import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin";

View file

@ -1,4 +1,4 @@
import { CooldownManager, PluginOptions, guildPlugin } from "knub";
import { CooldownManager, guildPlugin, PluginOptions } from "knub";
import { RoleAddCmd } from "./commands/RoleAddCmd";
import { RoleHelpCmd } from "./commands/RoleHelpCmd";
import { RoleRemoveCmd } from "./commands/RoleRemoveCmd";

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { GuildLogs } from "../../data/GuildLogs";
import { GuildSavedMessages } from "../../data/GuildSavedMessages";
import { GuildSlowmodes } from "../../data/GuildSlowmodes";

View file

@ -1,4 +1,4 @@
import { Message } from "discord.js";
import { Message, TextBasedChannelFields } from "discord.js";
import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
import { noop } from "../../../utils";
import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions";
@ -26,7 +26,7 @@ export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) {
return;
}
const initMsg = await msg.channel.send("Disabling slowmode...");
const initMsg = await (msg.channel as TextBasedChannelFields).send("Disabling slowmode...");
// Disable bot-maintained slowmode
let failedUsers: string[] = [];

View file

@ -2,7 +2,7 @@ import { GuildTextBasedChannel, Snowflake } from "discord.js";
import { GuildPluginData } from "knub";
import { LogType } from "../../../data/LogType";
import { logger } from "../../../logger";
import { UnknownUser, isDiscordAPIError, verboseChannelMention, verboseUserMention } from "../../../utils";
import { isDiscordAPIError, UnknownUser, verboseChannelMention, verboseUserMention } from "../../../utils";
import { LogsPlugin } from "../../Logs/LogsPlugin";
import { SlowmodePluginType } from "../types";

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { GuildArchives } from "../../data/GuildArchives";
import { GuildLogs } from "../../data/GuildLogs";
import { GuildMutes } from "../../data/GuildMutes";

View file

@ -9,7 +9,7 @@ import { logger } from "../../../logger";
import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin";
import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin";
import { MuteResult } from "../../../plugins/Mutes/types";
import { DBDateFormat, convertDelayStringToMS, noop, resolveMember, trimLines } from "../../../utils";
import { convertDelayStringToMS, DBDateFormat, noop, resolveMember, trimLines } from "../../../utils";
import { LogsPlugin } from "../../Logs/LogsPlugin";
import { RecentActionType, SpamPluginType, TBaseSingleSpamConfig } from "../types";
import { addRecentAction } from "./addRecentAction";

View file

@ -1,4 +1,4 @@
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import { GuildSavedMessages } from "../../data/GuildSavedMessages";
import { GuildStarboardMessages } from "../../data/GuildStarboardMessages";
import { GuildStarboardReactions } from "../../data/GuildStarboardReactions";

View file

@ -1,6 +1,6 @@
import { GuildChannel, Message } from "discord.js";
import path from "path";
import { EMPTY_CHAR, EmbedWith, renderUsername } from "../../../utils";
import { EmbedWith, EMPTY_CHAR, renderUsername } from "../../../utils";
const imageAttachmentExtensions = ["jpeg", "jpg", "png", "gif", "webp"];
const audioAttachmentExtensions = ["wav", "mp3", "m4a"];

View file

@ -1,6 +1,6 @@
import { Snowflake } from "discord.js";
import humanizeDuration from "humanize-duration";
import { PluginOptions, guildPlugin } from "knub";
import { guildPlugin, PluginOptions } from "knub";
import moment from "moment-timezone";
import { GuildArchives } from "../../data/GuildArchives";
import { GuildLogs } from "../../data/GuildLogs";

View file

@ -1,6 +1,6 @@
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
import { TemplateParseError, parseTemplate } from "../../../templateFormatter";
import { parseTemplate, TemplateParseError } from "../../../templateFormatter";
import { tagsCmd } from "../types";
export const TagCreateCmd = tagsCmd({

View file

@ -2,6 +2,7 @@ import escapeStringRegexp from "escape-string-regexp";
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { createChunkedMessage } from "../../../utils";
import { tagsCmd } from "../types";
import { TextChannel } from "discord.js";
export const TagListCmd = tagsCmd({
trigger: ["tag list", "tags", "taglist"],
@ -46,6 +47,6 @@ export const TagListCmd = tagsCmd({
.map((key) => `[${key}] ${tagGroups[key].join(", ")}`)
.join("\n");
createChunkedMessage(msg.channel, `Available tags (use with ${prefix}tag): \`\`\`${tagList}\`\`\``);
createChunkedMessage(msg.channel as TextChannel, `Available tags (use with ${prefix}tag): \`\`\`${tagList}\`\`\``);
},
});

View file

@ -1,5 +1,5 @@
import { ExtendedMatchParams, GuildPluginData } from "knub";
import { TTag, TagsPluginType } from "../types";
import { TagsPluginType, TTag } from "../types";
export async function findTagByName(
pluginData: GuildPluginData<TagsPluginType>,

View file

@ -2,7 +2,7 @@ import { GuildMember } from "discord.js";
import escapeStringRegexp from "escape-string-regexp";
import { ExtendedMatchParams, GuildPluginData } from "knub";
import { StrictMessageContent } from "../../../utils";
import { TTagCategory, TagsPluginType } from "../types";
import { TagsPluginType, TTagCategory } from "../types";
import { renderTagFromString } from "./renderTagFromString";
interface BaseResult {

View file

@ -1,7 +1,7 @@
import { ExtendedMatchParams, GuildPluginData } from "knub";
import { TemplateSafeValue, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter";
import { StrictMessageContent, renderRecursively } from "../../../utils";
import { TTag, TagsPluginType } from "../types";
import { renderTemplate, TemplateSafeValue, TemplateSafeValueContainer } from "../../../templateFormatter";
import { renderRecursively, StrictMessageContent } from "../../../utils";
import { TagsPluginType, TTag } from "../types";
import { findTagByName } from "./findTagByName";
const MAX_TAG_FN_CALLS = 25;

Some files were not shown because too many files have changed in this diff Show more