summary refs log tree commit diff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/util/config/types/GifConfiguration.ts2
-rw-r--r--src/util/dtos/DmChannelDTO.ts8
-rw-r--r--src/util/dtos/ReadyGuildDTO.ts16
-rw-r--r--src/util/entities/Application.ts14
-rw-r--r--src/util/entities/AuditLog.ts4
-rw-r--r--src/util/entities/BackupCodes.ts4
-rw-r--r--src/util/entities/BaseClass.ts9
-rw-r--r--src/util/entities/Channel.ts14
-rw-r--r--src/util/entities/ConnectedAccount.ts6
-rw-r--r--src/util/entities/Emoji.ts1
-rw-r--r--src/util/entities/Encryption.ts26
-rw-r--r--src/util/entities/Guild.ts8
-rw-r--r--src/util/entities/Member.ts25
-rw-r--r--src/util/entities/ReadState.ts1
-rw-r--r--src/util/entities/StickerPack.ts1
-rw-r--r--src/util/entities/Team.ts1
-rw-r--r--src/util/entities/User.ts19
-rw-r--r--src/util/imports/OrmUtils.ts25
-rw-r--r--src/util/interfaces/Event.ts12
-rw-r--r--src/util/interfaces/Interaction.ts2
-rw-r--r--src/util/schemas/ChannelPermissionOverwriteSchema.ts3
-rw-r--r--src/util/schemas/IdentifySchema.ts12
-rw-r--r--src/util/schemas/LazyRequestSchema.ts8
-rw-r--r--src/util/schemas/MessageCreateSchema.ts9
-rw-r--r--src/util/schemas/UserSettingsSchema.ts2
-rw-r--r--src/util/schemas/Validator.ts10
-rw-r--r--src/util/util/Array.ts4
-rw-r--r--src/util/util/AutoUpdate.ts5
-rw-r--r--src/util/util/BitField.ts4
-rw-r--r--src/util/util/Config.ts10
-rw-r--r--src/util/util/Constants.ts2
-rw-r--r--src/util/util/Database.ts5
-rw-r--r--src/util/util/Email.ts30
-rw-r--r--src/util/util/Event.ts30
-rw-r--r--src/util/util/FieldError.ts2
-rw-r--r--src/util/util/Permissions.ts37
-rw-r--r--src/util/util/Rights.ts12
-rw-r--r--src/util/util/Sentry.ts6
-rw-r--r--src/util/util/Snowflake.ts9
-rw-r--r--src/util/util/String.ts3
-rw-r--r--src/util/util/Token.ts25
-rw-r--r--src/util/util/TraverseDirectory.ts2
-rw-r--r--src/util/util/cdn.ts4
43 files changed, 208 insertions, 224 deletions
diff --git a/src/util/config/types/GifConfiguration.ts b/src/util/config/types/GifConfiguration.ts
index a623448c..0e5583fa 100644
--- a/src/util/config/types/GifConfiguration.ts
+++ b/src/util/config/types/GifConfiguration.ts
@@ -18,6 +18,6 @@
 
 export class GifConfiguration {
 	enabled: boolean = true;
-	provider: "tenor" = "tenor"; // more coming soon
+	provider = "tenor" as const; // more coming soon
 	apiKey?: string = "LIVDSRZULELA";
 }
diff --git a/src/util/dtos/DmChannelDTO.ts b/src/util/dtos/DmChannelDTO.ts
index 9d4d8dc3..02f7e8f3 100644
--- a/src/util/dtos/DmChannelDTO.ts
+++ b/src/util/dtos/DmChannelDTO.ts
@@ -44,16 +44,14 @@ export class DmChannelDTO {
 		obj.type = channel.type;
 		obj.recipients = (
 			await Promise.all(
-				channel
-					.recipients!.filter(
-						(r) => !excluded_recipients.includes(r.user_id),
-					)
+				channel.recipients
+					?.filter((r) => !excluded_recipients.includes(r.user_id))
 					.map(async (r) => {
 						return await User.findOneOrFail({
 							where: { id: r.user_id },
 							select: PublicUserProjection,
 						});
-					}),
+					}) || [],
 			)
 		).map((u) => new MinimalPublicUserDTO(u));
 		return obj;
diff --git a/src/util/dtos/ReadyGuildDTO.ts b/src/util/dtos/ReadyGuildDTO.ts
index 38303aed..97e6931f 100644
--- a/src/util/dtos/ReadyGuildDTO.ts
+++ b/src/util/dtos/ReadyGuildDTO.ts
@@ -23,7 +23,7 @@ export interface IReadyGuildDTO {
 	channels: Channel[];
 	data_mode: string; // what is this
 	emojis: Emoji[];
-	guild_scheduled_events: any[];
+	guild_scheduled_events: unknown[]; // TODO
 	id: string;
 	large: boolean | undefined;
 	lazy: boolean;
@@ -57,12 +57,12 @@ export interface IReadyGuildDTO {
 		max_video_channel_users: number | undefined;
 		max_members: number | undefined;
 		nsfw_level: number | undefined;
-		hub_type?: any | null; // ????
+		hub_type?: unknown | null; // ????
 	};
 	roles: Role[];
-	stage_instances: any[];
+	stage_instances: unknown[];
 	stickers: Sticker[];
-	threads: any[];
+	threads: unknown[];
 	version: string;
 }
 
@@ -71,7 +71,7 @@ export class ReadyGuildDTO implements IReadyGuildDTO {
 	channels: Channel[];
 	data_mode: string; // what is this
 	emojis: Emoji[];
-	guild_scheduled_events: any[];
+	guild_scheduled_events: unknown[];
 	id: string;
 	large: boolean | undefined;
 	lazy: boolean;
@@ -105,12 +105,12 @@ export class ReadyGuildDTO implements IReadyGuildDTO {
 		max_video_channel_users: number | undefined;
 		max_members: number | undefined;
 		nsfw_level: number | undefined;
-		hub_type?: any | null; // ????
+		hub_type?: unknown | null; // ????
 	};
 	roles: Role[];
-	stage_instances: any[];
+	stage_instances: unknown[];
 	stickers: Sticker[];
-	threads: any[];
+	threads: unknown[];
 	version: string;
 
 	constructor(guild: Guild) {
diff --git a/src/util/entities/Application.ts b/src/util/entities/Application.ts
index 94a015e9..94709320 100644
--- a/src/util/entities/Application.ts
+++ b/src/util/entities/Application.ts
@@ -16,16 +16,8 @@
 	along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 
-import {
-	Column,
-	Entity,
-	JoinColumn,
-	ManyToOne,
-	OneToOne,
-	RelationId,
-} from "typeorm";
+import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from "typeorm";
 import { BaseClass } from "./BaseClass";
-import { Guild } from "./Guild";
 import { Team } from "./Team";
 import { User } from "./User";
 
@@ -44,7 +36,7 @@ export class Application extends BaseClass {
 	summary: string = "";
 
 	@Column({ type: "simple-json", nullable: true })
-	type?: any;
+	type?: object; // TODO: this type is bad
 
 	@Column()
 	hook: boolean = true;
@@ -176,6 +168,6 @@ export interface ApplicationCommandInteractionData {
 
 export interface ApplicationCommandInteractionDataOption {
 	name: string;
-	value?: any;
+	value?: unknown;
 	options?: ApplicationCommandInteractionDataOption[];
 }
diff --git a/src/util/entities/AuditLog.ts b/src/util/entities/AuditLog.ts
index 68893ea8..0cc2fc04 100644
--- a/src/util/entities/AuditLog.ts
+++ b/src/util/entities/AuditLog.ts
@@ -173,8 +173,8 @@ export interface AuditLogChangeValue {
 	explicit_content_filter?: number;
 	default_message_notifications?: number;
 	vanity_url_code?: string;
-	$add?: {}[];
-	$remove?: {}[];
+	$add?: object[]; // TODO: These types are bad.
+	$remove?: object[];
 	prune_delete_days?: number;
 	widget_enabled?: boolean;
 	widget_channel_id?: string;
diff --git a/src/util/entities/BackupCodes.ts b/src/util/entities/BackupCodes.ts
index 1245ecd1..467e1fe3 100644
--- a/src/util/entities/BackupCodes.ts
+++ b/src/util/entities/BackupCodes.ts
@@ -16,7 +16,7 @@
 	along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
+import { Column, Entity, JoinColumn, ManyToOne } from "typeorm";
 import { BaseClass } from "./BaseClass";
 import { User } from "./User";
 import crypto from "crypto";
@@ -38,7 +38,7 @@ export class BackupCode extends BaseClass {
 }
 
 export function generateMfaBackupCodes(user_id: string) {
-	let backup_codes: BackupCode[] = [];
+	const backup_codes: BackupCode[] = [];
 	for (let i = 0; i < 10; i++) {
 		const code = BackupCode.create({
 			user: { id: user_id },
diff --git a/src/util/entities/BaseClass.ts b/src/util/entities/BaseClass.ts
index e3df5ad4..445b3fc9 100644
--- a/src/util/entities/BaseClass.ts
+++ b/src/util/entities/BaseClass.ts
@@ -29,7 +29,7 @@ import { getDatabase } from "../util/Database";
 import { OrmUtils } from "../imports/OrmUtils";
 
 export class BaseClassWithoutId extends BaseEntity {
-	private get construct(): any {
+	private get construct() {
 		return this.constructor;
 	}
 
@@ -37,19 +37,24 @@ export class BaseClassWithoutId extends BaseEntity {
 		return getDatabase()?.getMetadata(this.construct);
 	}
 
-	assign(props: any) {
+	assign(props: object) {
 		OrmUtils.mergeDeep(this, props);
 		return this;
 	}
 
+	// TODO: fix eslint
+	// eslint-disable-next-line @typescript-eslint/no-explicit-any
 	toJSON(): any {
 		return Object.fromEntries(
+			// eslint-disable-next-line @typescript-eslint/ban-ts-comment, @typescript-eslint/no-non-null-assertion
 			this.metadata!.columns // @ts-ignore
 				.map((x) => [x.propertyName, this[x.propertyName]])
 				.concat(
+					// eslint-disable-next-line @typescript-eslint/ban-ts-comment
 					// @ts-ignore
 					this.metadata.relations.map((x) => [
 						x.propertyName,
+						// eslint-disable-next-line @typescript-eslint/ban-ts-comment
 						// @ts-ignore
 						this[x.propertyName],
 					]),
diff --git a/src/util/entities/Channel.ts b/src/util/entities/Channel.ts
index 2e5f030c..1f128713 100644
--- a/src/util/entities/Channel.ts
+++ b/src/util/entities/Channel.ts
@@ -35,7 +35,6 @@ import {
 	Snowflake,
 	trimSpecial,
 	InvisibleCharacters,
-	ChannelTypes,
 } from "../util";
 import { ChannelCreateEvent, ChannelRecipientRemoveEvent } from "../interfaces";
 import { Recipient } from "./Recipient";
@@ -219,7 +218,7 @@ export class Channel extends BaseClass {
 				!guild.features.includes("ALLOW_INVALID_CHANNEL_NAMES") &&
 				channel.name
 			) {
-				for (var character of InvisibleCharacters)
+				for (const character of InvisibleCharacters)
 					if (channel.name.includes(character))
 						throw new HTTPError(
 							"Channel name cannot include invalid characters",
@@ -237,7 +236,7 @@ export class Channel extends BaseClass {
 							403,
 						);
 
-					if (channel.name.match(/\-\-+/g))
+					if (channel.name.match(/--+/g))
 						throw new HTTPError(
 							"Channel name cannot include multiple adjacent dashes.",
 							403,
@@ -344,8 +343,9 @@ export class Channel extends BaseClass {
 			relations: ["channel", "channel.recipients"],
 		});
 
-		for (let ur of userRecipients) {
-			let re = ur.channel.recipients!.map((r) => r.user_id);
+		for (const ur of userRecipients) {
+			if (!ur.channel.recipients) continue;
+			const re = ur.channel.recipients.map((r) => r.user_id);
 			if (re.length === channelRecipients.length) {
 				if (containsAll(re, channelRecipients)) {
 					if (channel == null) {
@@ -380,8 +380,8 @@ export class Channel extends BaseClass {
 
 		const channel_dto = await DmChannelDTO.from(channel);
 
-		if (type === ChannelType.GROUP_DM) {
-			for (let recipient of channel.recipients!) {
+		if (type === ChannelType.GROUP_DM && channel.recipients) {
+			for (const recipient of channel.recipients) {
 				await emitEvent({
 					event: "CHANNEL_CREATE",
 					data: channel_dto.excludedRecipients([recipient.user_id]),
diff --git a/src/util/entities/ConnectedAccount.ts b/src/util/entities/ConnectedAccount.ts
index 1d0d0586..9f0ce35e 100644
--- a/src/util/entities/ConnectedAccount.ts
+++ b/src/util/entities/ConnectedAccount.ts
@@ -20,8 +20,10 @@ import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
 import { BaseClass } from "./BaseClass";
 import { User } from "./User";
 
-export interface PublicConnectedAccount
-	extends Pick<ConnectedAccount, "name" | "type" | "verified"> {}
+export type PublicConnectedAccount = Pick<
+	ConnectedAccount,
+	"name" | "type" | "verified"
+>;
 
 @Entity("connected_accounts")
 export class ConnectedAccount extends BaseClass {
diff --git a/src/util/entities/Emoji.ts b/src/util/entities/Emoji.ts
index 95a641f1..94ce3d54 100644
--- a/src/util/entities/Emoji.ts
+++ b/src/util/entities/Emoji.ts
@@ -20,7 +20,6 @@ import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
 import { User } from ".";
 import { BaseClass } from "./BaseClass";
 import { Guild } from "./Guild";
-import { Role } from "./Role";
 
 @Entity("emojis")
 export class Emoji extends BaseClass {
diff --git a/src/util/entities/Encryption.ts b/src/util/entities/Encryption.ts
index db9d0983..016b4331 100644
--- a/src/util/entities/Encryption.ts
+++ b/src/util/entities/Encryption.ts
@@ -16,32 +16,8 @@
 	along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 
-import {
-	Column,
-	Entity,
-	JoinColumn,
-	ManyToOne,
-	OneToMany,
-	RelationId,
-} from "typeorm";
+import { Column, Entity } from "typeorm";
 import { BaseClass } from "./BaseClass";
-import { Guild } from "./Guild";
-import { PublicUserProjection, User } from "./User";
-import { HTTPError } from "lambert-server";
-import {
-	containsAll,
-	emitEvent,
-	getPermission,
-	Snowflake,
-	trimSpecial,
-	InvisibleCharacters,
-} from "../util";
-import { BitField, BitFieldResolvable, BitFlag } from "../util/BitField";
-import { Recipient } from "./Recipient";
-import { Message } from "./Message";
-import { ReadState } from "./ReadState";
-import { Invite } from "./Invite";
-import { DmChannelDTO } from "../dtos";
 
 @Entity("security_settings")
 export class SecuritySettings extends BaseClass {
diff --git a/src/util/entities/Guild.ts b/src/util/entities/Guild.ts
index 9f300334..c835f5fc 100644
--- a/src/util/entities/Guild.ts
+++ b/src/util/entities/Guild.ts
@@ -20,10 +20,8 @@ import {
 	Column,
 	Entity,
 	JoinColumn,
-	ManyToMany,
 	ManyToOne,
 	OneToMany,
-	OneToOne,
 	RelationId,
 } from "typeorm";
 import { Config, handleFile, Snowflake } from "..";
@@ -370,12 +368,12 @@ export class Guild extends BaseClass {
 			}
 		});
 
-		for (const channel of body.channels?.sort((a, b) =>
+		for (const channel of body.channels.sort((a) =>
 			a.parent_id ? 1 : -1,
 		)) {
-			var id = ids.get(channel.id) || Snowflake.generate();
+			const id = ids.get(channel.id) || Snowflake.generate();
 
-			var parent_id = ids.get(channel.parent_id);
+			const parent_id = ids.get(channel.parent_id);
 
 			await Channel.createChannel(
 				{ ...channel, guild_id, id, parent_id },
diff --git a/src/util/entities/Member.ts b/src/util/entities/Member.ts
index 801b5738..c68fe215 100644
--- a/src/util/entities/Member.ts
+++ b/src/util/entities/Member.ts
@@ -33,7 +33,7 @@ import {
 	RelationId,
 } from "typeorm";
 import { Guild } from "./Guild";
-import { Config, emitEvent, FieldErrors } from "../util";
+import { Config, emitEvent } from "../util";
 import {
 	GuildCreateEvent,
 	GuildDeleteEvent,
@@ -212,12 +212,16 @@ export class Member extends BaseClassWithoutId {
 	}
 
 	static async addRole(user_id: string, guild_id: string, role_id: string) {
-		const [member, role] = await Promise.all([
+		const [member] = await Promise.all([
 			Member.findOneOrFail({
 				where: { id: user_id, guild_id },
 				relations: ["user", "roles"], // we don't want to load  the role objects just the ids
-				//@ts-ignore
-				select: ["index", "roles.id"], // TODO fix type
+				select: {
+					index: true,
+					roles: {
+						id: true,
+					},
+				},
 			}),
 			Role.findOneOrFail({
 				where: { id: role_id, guild_id },
@@ -249,8 +253,12 @@ export class Member extends BaseClassWithoutId {
 			Member.findOneOrFail({
 				where: { id: user_id, guild_id },
 				relations: ["user", "roles"], // we don't want to load  the role objects just the ids
-				//@ts-ignore
-				select: ["roles.id", "index"], // TODO: fix type
+				select: {
+					index: true,
+					roles: {
+						id: true,
+					},
+				},
 			}),
 			await Role.findOneOrFail({ where: { id: role_id, guild_id } }),
 		]);
@@ -327,7 +335,7 @@ export class Member extends BaseClassWithoutId {
 				guild_id,
 				user: {
 					sessions: {
-						status: Not("invisible" as "invisible"), // lol typescript?
+						status: Not("invisible" as const), // lol typescript?
 					},
 				},
 			},
@@ -506,8 +514,7 @@ export const PublicMemberProjection: PublicMemberKeys[] = [
 	"premium_since",
 ];
 
-// @ts-ignore
-export type PublicMember = Pick<Member, Omit<PublicMemberKeys, "roles">> & {
+export type PublicMember = Omit<Pick<Member, PublicMemberKeys>, "roles"> & {
 	user: PublicUser;
 	roles: string[]; // only role ids not objects
 };
diff --git a/src/util/entities/ReadState.ts b/src/util/entities/ReadState.ts
index a907b701..825beb03 100644
--- a/src/util/entities/ReadState.ts
+++ b/src/util/entities/ReadState.ts
@@ -26,7 +26,6 @@ import {
 } from "typeorm";
 import { BaseClass } from "./BaseClass";
 import { Channel } from "./Channel";
-import { Message } from "./Message";
 import { User } from "./User";
 
 // for read receipts
diff --git a/src/util/entities/StickerPack.ts b/src/util/entities/StickerPack.ts
index 911d8d05..ce8d5e87 100644
--- a/src/util/entities/StickerPack.ts
+++ b/src/util/entities/StickerPack.ts
@@ -22,7 +22,6 @@ import {
 	JoinColumn,
 	ManyToOne,
 	OneToMany,
-	OneToOne,
 	RelationId,
 } from "typeorm";
 import { Sticker } from ".";
diff --git a/src/util/entities/Team.ts b/src/util/entities/Team.ts
index 730ff75f..82859409 100644
--- a/src/util/entities/Team.ts
+++ b/src/util/entities/Team.ts
@@ -20,7 +20,6 @@ import {
 	Column,
 	Entity,
 	JoinColumn,
-	ManyToMany,
 	ManyToOne,
 	OneToMany,
 	RelationId,
diff --git a/src/util/entities/User.ts b/src/util/entities/User.ts
index ed9e3884..658584c3 100644
--- a/src/util/entities/User.ts
+++ b/src/util/entities/User.ts
@@ -17,8 +17,6 @@
 */
 
 import {
-	BeforeInsert,
-	BeforeUpdate,
 	Column,
 	Entity,
 	FindOneOptions,
@@ -34,6 +32,7 @@ import { Member } from "./Member";
 import { UserSettings } from "./UserSettings";
 import { Session } from "./Session";
 import { Config, FieldErrors, Snowflake, trimSpecial, adjustEmail } from "..";
+import { Request } from "express";
 
 export enum PublicUserEnum {
 	username,
@@ -80,7 +79,7 @@ export const PrivateUserProjection = [
 // Private user data that should never get sent to the client
 export type PublicUser = Pick<User, PublicUserKeys>;
 
-export interface UserPublic extends Pick<User, PublicUserKeys> {}
+export type UserPublic = Pick<User, PublicUserKeys>;
 
 export interface UserPrivate extends Pick<User, PrivateUserKeys> {
 	locale: string;
@@ -266,6 +265,7 @@ export class User extends BaseClass {
 	}
 
 	toPublicUser() {
+		// eslint-disable-next-line @typescript-eslint/no-explicit-any
 		const user: any = {};
 		PublicUserProjection.forEach((x) => {
 			user[x] = this[x];
@@ -277,6 +277,7 @@ export class User extends BaseClass {
 		return await User.findOneOrFail({
 			where: { id: user_id },
 			...opts,
+			// eslint-disable-next-line @typescript-eslint/ban-ts-comment
 			//@ts-ignore
 			select: [...PublicUserProjection, ...(opts?.select || [])], // TODO: fix
 		});
@@ -328,7 +329,6 @@ export class User extends BaseClass {
 		email,
 		username,
 		password,
-		date_of_birth,
 		id,
 		req,
 	}: {
@@ -337,7 +337,7 @@ export class User extends BaseClass {
 		email?: string;
 		date_of_birth?: Date; // "2000-04-03"
 		id?: string;
-		req?: any;
+		req?: Request;
 	}) {
 		// trim special uf8 control characters -> Backspace, Newline, ...
 		username = trimSpecial(username);
@@ -348,7 +348,8 @@ export class User extends BaseClass {
 			throw FieldErrors({
 				username: {
 					code: "USERNAME_TOO_MANY_USERS",
-					message: req.t("auth:register.USERNAME_TOO_MANY_USERS"),
+					message:
+						req?.t("auth:register.USERNAME_TOO_MANY_USERS") || "",
 				},
 			});
 		}
@@ -357,7 +358,7 @@ export class User extends BaseClass {
 		// appearently discord doesn't save the date of birth and just calculate if nsfw is allowed
 		// if nsfw_allowed is null/undefined it'll require date_of_birth to set it to true/false
 		const language =
-			req.language === "en" ? "en-US" : req.language || "en-US";
+			req?.language === "en" ? "en-US" : req?.language || "en-US";
 
 		const settings = UserSettings.create({
 			locale: language,
@@ -386,7 +387,9 @@ export class User extends BaseClass {
 		setImmediate(async () => {
 			if (Config.get().guild.autoJoin.enabled) {
 				for (const guild of Config.get().guild.autoJoin.guilds || []) {
-					await Member.addToGuild(user.id, guild).catch((e) => {});
+					await Member.addToGuild(user.id, guild).catch((e) =>
+						console.error("[Autojoin]", e),
+					);
 				}
 			}
 		});
diff --git a/src/util/imports/OrmUtils.ts b/src/util/imports/OrmUtils.ts
index e6551471..039c81fe 100644
--- a/src/util/imports/OrmUtils.ts
+++ b/src/util/imports/OrmUtils.ts
@@ -1,25 +1,10 @@
-/*
-	Fosscord: A FOSS re-implementation and extension of the Discord.com backend.
-	Copyright (C) 2023 Fosscord and Fosscord Contributors
-	
-	This program is free software: you can redistribute it and/or modify
-	it under the terms of the GNU Affero General Public License as published
-	by the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-	
-	This program is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU Affero General Public License for more details.
-	
-	You should have received a copy of the GNU Affero General Public License
-	along with this program.  If not, see <https://www.gnu.org/licenses/>.
-*/
-
-//source: https://github.com/typeorm/typeorm/blob/master/src/util/OrmUtils.ts
+// source: https://github.com/typeorm/typeorm/blob/master/src/util/OrmUtils.ts
+// Copyright (c) 2015-2022 TypeORM. http://typeorm.github.io
+/* eslint-disable @typescript-eslint/no-explicit-any */
+// @fc-license-skip
 export class OrmUtils {
 	// Checks if it's an object made by Object.create(null), {} or new Object()
-	private static isPlainObject(item: any) {
+	private static isPlainObject(item: unknown) {
 		if (item === null || item === undefined) {
 			return false;
 		}
diff --git a/src/util/interfaces/Event.ts b/src/util/interfaces/Event.ts
index e902cdf3..c3bfbf9b 100644
--- a/src/util/interfaces/Event.ts
+++ b/src/util/interfaces/Event.ts
@@ -39,6 +39,7 @@ import {
 	Presence,
 	UserSettings,
 	IReadyGuildDTO,
+	ReadState,
 } from "@fosscord/util";
 
 export interface Event {
@@ -47,6 +48,7 @@ export interface Event {
 	channel_id?: string;
 	created_at?: Date;
 	event: EVENT;
+	// eslint-disable-next-line @typescript-eslint/no-explicit-any
 	data?: any;
 }
 
@@ -103,12 +105,12 @@ export interface ReadyEventData {
 		[number, [[number, [number, number]]]],
 		{ b: number; k: bigint[] }[],
 	][];
-	guild_join_requests?: any[]; // ? what is this? this is new
+	guild_join_requests?: unknown[]; // ? what is this? this is new
 	shard?: [number, number];
 	user_settings?: UserSettings;
 	relationships?: PublicRelationship[]; // TODO
 	read_state: {
-		entries: any[]; // TODO
+		entries: ReadState[]; // TODO
 		partial: boolean;
 		version: number;
 	};
@@ -124,7 +126,7 @@ export interface ReadyEventData {
 	merged_members?: PublicMember[][];
 	// probably all users who the user is in contact with
 	users?: PublicUser[];
-	sessions: any[];
+	sessions: unknown[];
 }
 
 export interface ReadyEvent extends Event {
@@ -178,7 +180,7 @@ export interface GuildCreateEvent extends Event {
 		joined_at: Date;
 		// TODO: add them to guild
 		guild_scheduled_events: never[];
-		guild_hashes: {};
+		guild_hashes: unknown;
 		presences: never[];
 		stage_instances: never[];
 		threads: never[];
@@ -408,7 +410,7 @@ export interface TypingStartEvent extends Event {
 
 export interface UserUpdateEvent extends Event {
 	event: "USER_UPDATE";
-	data: User;
+	data: Omit<User, "data">;
 }
 
 export interface UserDeleteEvent extends Event {
diff --git a/src/util/interfaces/Interaction.ts b/src/util/interfaces/Interaction.ts
index 8695fca9..4158eda1 100644
--- a/src/util/interfaces/Interaction.ts
+++ b/src/util/interfaces/Interaction.ts
@@ -21,7 +21,7 @@ import { AllowedMentions, Embed } from "../entities/Message";
 export interface Interaction {
 	id: string;
 	type: InteractionType;
-	data?: {};
+	data?: object; // TODO typing
 	guild_id: string;
 	channel_id: string;
 	member_id: string;
diff --git a/src/util/schemas/ChannelPermissionOverwriteSchema.ts b/src/util/schemas/ChannelPermissionOverwriteSchema.ts
index 97fe9dee..62d0ad14 100644
--- a/src/util/schemas/ChannelPermissionOverwriteSchema.ts
+++ b/src/util/schemas/ChannelPermissionOverwriteSchema.ts
@@ -18,5 +18,4 @@
 
 import { ChannelPermissionOverwrite } from "@fosscord/util";
 
-export interface ChannelPermissionOverwriteSchema
-	extends ChannelPermissionOverwrite {}
+export type ChannelPermissionOverwriteSchema = ChannelPermissionOverwrite;
diff --git a/src/util/schemas/IdentifySchema.ts b/src/util/schemas/IdentifySchema.ts
index 18ab2b49..9bb14ca3 100644
--- a/src/util/schemas/IdentifySchema.ts
+++ b/src/util/schemas/IdentifySchema.ts
@@ -18,6 +18,8 @@
 
 import { ActivitySchema } from "@fosscord/util";
 
+// TODO: Need a way to allow camalCase and pascal_case without just duplicating the schema
+
 export const IdentifySchema = {
 	token: String,
 	$intents: BigInt, // discord uses a Integer for bitfields we use bigints tho. | instanceOf will automatically convert the Number to a BigInt
@@ -98,7 +100,7 @@ export interface IdentifySchema {
 		referring_domain_current?: string;
 		release_channel?: "stable" | "dev" | "ptb" | "canary";
 		client_build_number?: number;
-		client_event_source?: any;
+		client_event_source?: string;
 		client_version?: string;
 		system_locale?: string;
 	};
@@ -111,23 +113,23 @@ export interface IdentifySchema {
 	guild_subscriptions?: boolean;
 	capabilities?: number;
 	client_state?: {
-		guild_hashes?: any;
+		guild_hashes?: unknown;
 		highest_last_message_id?: string | number;
 		read_state_version?: number;
 		user_guild_settings_version?: number;
 		user_settings_version?: number;
 		useruser_guild_settings_version?: number;
 		private_channels_version?: number;
-		guild_versions?: any;
+		guild_versions?: unknown;
 		api_code_version?: number;
 	};
 	clientState?: {
-		guildHashes?: any;
+		guildHashes?: unknown;
 		highestLastMessageId?: string | number;
 		readStateVersion?: number;
 		userGuildSettingsVersion?: number;
 		useruserGuildSettingsVersion?: number;
-		guildVersions?: any;
+		guildVersions?: unknown;
 		apiCodeVersion?: number;
 	};
 	v?: number;
diff --git a/src/util/schemas/LazyRequestSchema.ts b/src/util/schemas/LazyRequestSchema.ts
index 02fe0d8b..7cf3fd36 100644
--- a/src/util/schemas/LazyRequestSchema.ts
+++ b/src/util/schemas/LazyRequestSchema.ts
@@ -22,8 +22,8 @@ export interface LazyRequestSchema {
 	activities?: boolean;
 	threads?: boolean;
 	typing?: true;
-	members?: any[];
-	thread_member_lists?: any[];
+	members?: unknown[];
+	thread_member_lists?: unknown[];
 }
 
 export const LazyRequestSchema = {
@@ -32,6 +32,6 @@ export const LazyRequestSchema = {
 	$channels: Object,
 	$typing: Boolean,
 	$threads: Boolean,
-	$members: [] as any[],
-	$thread_member_lists: [] as any[],
+	$members: [] as unknown[],
+	$thread_member_lists: [] as unknown[],
 };
diff --git a/src/util/schemas/MessageCreateSchema.ts b/src/util/schemas/MessageCreateSchema.ts
index 1dd5d32c..4ee6e738 100644
--- a/src/util/schemas/MessageCreateSchema.ts
+++ b/src/util/schemas/MessageCreateSchema.ts
@@ -18,6 +18,11 @@
 
 import { Embed } from "@fosscord/util";
 
+type Attachment = {
+	id: string;
+	filename: string;
+};
+
 export interface MessageCreateSchema {
 	type?: number;
 	content?: string;
@@ -41,11 +46,11 @@ export interface MessageCreateSchema {
 		fail_if_not_exists?: boolean;
 	};
 	payload_json?: string;
-	file?: any;
+	file?: { filename: string };
 	/**
 	TODO: we should create an interface for attachments
 	TODO: OpenWAAO<-->attachment-style metadata conversion
 	**/
-	attachments?: any[];
+	attachments?: Attachment[];
 	sticker_ids?: string[];
 }
diff --git a/src/util/schemas/UserSettingsSchema.ts b/src/util/schemas/UserSettingsSchema.ts
index e25588c4..5a590b02 100644
--- a/src/util/schemas/UserSettingsSchema.ts
+++ b/src/util/schemas/UserSettingsSchema.ts
@@ -18,4 +18,4 @@
 
 import { UserSettings } from "@fosscord/util";
 
-export interface UserSettingsSchema extends Partial<UserSettings> {}
+export type UserSettingsSchema = Partial<UserSettings>;
diff --git a/src/util/schemas/Validator.ts b/src/util/schemas/Validator.ts
index 26a88ef9..3190dd05 100644
--- a/src/util/schemas/Validator.ts
+++ b/src/util/schemas/Validator.ts
@@ -45,7 +45,7 @@ export const ajv = new Ajv({
 
 addFormats(ajv);
 
-export function validateSchema<G>(schema: string, data: G): G {
+export function validateSchema<G extends object>(schema: string, data: G): G {
 	const valid = ajv.validate(schema, normalizeBody(data));
 	if (!valid) throw ajv.errors;
 	return data;
@@ -55,13 +55,13 @@ export function validateSchema<G>(schema: string, data: G): G {
 // this removes null values as ajv doesn't treat them as undefined
 // normalizeBody allows to handle circular structures without issues
 // taken from https://github.com/serverless/serverless/blob/master/lib/classes/ConfigSchemaHandler/index.js#L30 (MIT license)
-export const normalizeBody = (body: any = {}) => {
+export const normalizeBody = (body: object = {}) => {
 	const normalizedObjectsSet = new WeakSet();
-	const normalizeObject = (object: any) => {
+	const normalizeObject = (object: object) => {
 		if (normalizedObjectsSet.has(object)) return;
 		normalizedObjectsSet.add(object);
 		if (Array.isArray(object)) {
-			for (const [index, value] of object.entries()) {
+			for (const [, value] of object.entries()) {
 				if (typeof value === "object") normalizeObject(value);
 			}
 		} else {
@@ -75,6 +75,8 @@ export const normalizeBody = (body: any = {}) => {
 						key === "discovery_splash"
 					)
 						continue;
+					// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+					//@ts-ignore
 					delete object[key];
 				} else if (typeof value === "object") {
 					normalizeObject(value);
diff --git a/src/util/util/Array.ts b/src/util/util/Array.ts
index 1935fa7a..dbc75b85 100644
--- a/src/util/util/Array.ts
+++ b/src/util/util/Array.ts
@@ -16,6 +16,8 @@
 	along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 
-export function containsAll(arr: any[], target: any[]) {
+// TODO: remove this function.
+
+export function containsAll(arr: unknown[], target: unknown[]) {
 	return target.every((v) => arr.includes(v));
 }
diff --git a/src/util/util/AutoUpdate.ts b/src/util/util/AutoUpdate.ts
index 08836ea2..a4a97f3f 100644
--- a/src/util/util/AutoUpdate.ts
+++ b/src/util/util/AutoUpdate.ts
@@ -36,7 +36,7 @@ export function enableAutoUpdate(opts: {
 	downloadType?: "zip";
 }) {
 	if (!opts.checkInterval) return;
-	var interval = 1000 * 60 * 60 * 24;
+	const interval = 1000 * 60 * 60 * 24;
 	if (typeof opts.checkInterval === "number")
 		opts.checkInterval = 1000 * interval;
 
@@ -70,6 +70,7 @@ export function enableAutoUpdate(opts: {
 	});
 }
 
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
 async function download(url: string, dir: string) {
 	try {
 		// TODO: use file stream instead of buffer (to prevent crash because of high memory usage for big files)
@@ -99,7 +100,7 @@ async function getLatestVersion(url: string) {
 	try {
 		const agent = new ProxyAgent();
 		const response = await fetch(url, { agent });
-		const content = (await response.json()) as any; // TODO: types
+		const content = await response.json();
 		return content.version;
 	} catch (error) {
 		throw new Error("[Auto update] check failed for " + url);
diff --git a/src/util/util/BitField.ts b/src/util/util/BitField.ts
index 62bc3c46..d8758327 100644
--- a/src/util/util/BitField.ts
+++ b/src/util/util/BitField.ts
@@ -6,7 +6,7 @@
 
 export type BitFieldResolvable =
 	| number
-	| BigInt
+	| bigint
 	| BitField
 	| string
 	| BitFieldResolvable[];
@@ -135,6 +135,7 @@ export class BitField {
 	 * @returns {number}
 	 */
 	static resolve(bit: BitFieldResolvable = BigInt(0)): bigint {
+		// eslint-disable-next-line @typescript-eslint/ban-ts-comment
 		// @ts-ignore
 		const FLAGS = this.FLAGS || this.constructor?.FLAGS;
 
@@ -152,6 +153,7 @@ export class BitField {
 		if (bit instanceof BitField) return bit.bitfield;
 
 		if (Array.isArray(bit)) {
+			// eslint-disable-next-line @typescript-eslint/ban-ts-comment
 			// @ts-ignore
 			const resolve = this.constructor?.resolve || this.resolve;
 			return bit
diff --git a/src/util/util/Config.ts b/src/util/util/Config.ts
index 4b2dbb0d..b83f1d7b 100644
--- a/src/util/util/Config.ts
+++ b/src/util/util/Config.ts
@@ -24,8 +24,8 @@ import { ConfigValue } from "../config";
 // TODO: yaml instead of json
 const overridePath = process.env.CONFIG_PATH ?? "";
 
-var config: ConfigValue;
-var pairs: ConfigEntity[];
+let config: ConfigValue;
+let pairs: ConfigEntity[];
 
 // TODO: use events to inform about config updates
 // Config keys are separated with _
@@ -84,6 +84,8 @@ export const Config = {
 };
 
 function applyConfig(val: ConfigValue) {
+	// TODO: typings
+	// eslint-disable-next-line @typescript-eslint/no-explicit-any
 	async function apply(obj: any, key = ""): Promise<any> {
 		if (typeof obj === "object" && obj !== null)
 			return Promise.all(
@@ -107,7 +109,9 @@ function applyConfig(val: ConfigValue) {
 }
 
 function pairsToConfig(pairs: ConfigEntity[]) {
-	var value: any = {};
+	// TODO: typings
+	// eslint-disable-next-line @typescript-eslint/no-explicit-any
+	const value: any = {};
 
 	pairs.forEach((p) => {
 		const keys = p.key.split("_");
diff --git a/src/util/util/Constants.ts b/src/util/util/Constants.ts
index d65fda58..1afdce49 100644
--- a/src/util/util/Constants.ts
+++ b/src/util/util/Constants.ts
@@ -1125,7 +1125,7 @@ export const MembershipStates = ["INSERTED", "INVITED", "ACCEPTED"];
 export const WebhookTypes = ["Custom", "Incoming", "Channel Follower"];
 
 function keyMirror(arr: string[]) {
-	let tmp = Object.create(null);
+	const tmp = Object.create(null);
 	for (const value of arr) tmp[value] = value;
 	return tmp;
 }
diff --git a/src/util/util/Database.ts b/src/util/util/Database.ts
index 38011b9c..e1a4003f 100644
--- a/src/util/util/Database.ts
+++ b/src/util/util/Database.ts
@@ -25,14 +25,14 @@ import path from "path";
 // UUID extension option is only supported with postgres
 // We want to generate all id's with Snowflakes that's why we have our own BaseEntity class
 
-var dbConnection: DataSource | undefined;
+let dbConnection: DataSource | undefined;
 
 // For typeorm cli
 if (!process.env) {
 	config();
 }
 
-let dbConnectionString =
+const dbConnectionString =
 	process.env.DATABASE || path.join(process.cwd(), "database.db");
 
 const DatabaseType = dbConnectionString.includes("://")
@@ -41,6 +41,7 @@ const DatabaseType = dbConnectionString.includes("://")
 const isSqlite = DatabaseType.includes("sqlite");
 
 const DataSourceOptions = new DataSource({
+	// eslint-disable-next-line @typescript-eslint/ban-ts-comment
 	//@ts-ignore type 'string' is not 'mysql' | 'sqlite' | 'mariadb' | etc etc
 	type: DatabaseType,
 	charset: "utf8mb4",
diff --git a/src/util/util/Email.ts b/src/util/util/Email.ts
index f45728fc..48d8cae1 100644
--- a/src/util/util/Email.ts
+++ b/src/util/util/Email.ts
@@ -17,27 +17,29 @@
 */
 
 export const EMAIL_REGEX =
-	/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+	/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
 
 export function adjustEmail(email?: string): string | undefined {
 	if (!email) return email;
 	// body parser already checked if it is a valid email
 	const parts = <RegExpMatchArray>email.match(EMAIL_REGEX);
-	// @ts-ignore
 	if (!parts || parts.length < 5) return undefined;
-	const domain = parts[5];
-	const user = parts[1];
 
-	// TODO: check accounts with uncommon email domains
-	if (domain === "gmail.com" || domain === "googlemail.com") {
-		// replace .dots and +alternatives -> Gmail Dot Trick https://support.google.com/mail/answer/7436150 and https://generator.email/blog/gmail-generator
-		let v = user.replace(/[.]|(\+.*)/g, "") + "@gmail.com";
-	}
+	return email;
+	// // TODO: The below code doesn't actually do anything.
+	// const domain = parts[5];
+	// const user = parts[1];
 
-	if (domain === "google.com") {
-		// replace .dots and +alternatives -> Google Staff GMail Dot Trick
-		let v = user.replace(/[.]|(\+.*)/g, "") + "@google.com";
-	}
+	// // TODO: check accounts with uncommon email domains
+	// if (domain === "gmail.com" || domain === "googlemail.com") {
+	// 	// replace .dots and +alternatives -> Gmail Dot Trick https://support.google.com/mail/answer/7436150 and https://generator.email/blog/gmail-generator
+	// 	const v = user.replace(/[.]|(\+.*)/g, "") + "@gmail.com";
+	// }
 
-	return email;
+	// if (domain === "google.com") {
+	// 	// replace .dots and +alternatives -> Google Staff GMail Dot Trick
+	// 	const v = user.replace(/[.]|(\+.*)/g, "") + "@google.com";
+	// }
+
+	// return email;
 }
diff --git a/src/util/util/Event.ts b/src/util/util/Event.ts
index 5e01e644..79be1a10 100644
--- a/src/util/util/Event.ts
+++ b/src/util/util/Event.ts
@@ -55,6 +55,7 @@ export async function emitEvent(payload: Omit<Event, "created_at">) {
 export async function initEvent() {
 	await RabbitMQ.init(); // does nothing if rabbitmq is not setup
 	if (RabbitMQ.connection) {
+		// empty on purpose?
 	} else {
 		// use event emitter
 		// use process messages
@@ -62,9 +63,9 @@ export async function initEvent() {
 }
 
 export interface EventOpts extends Event {
-	acknowledge?: Function;
+	acknowledge?: () => unknown;
 	channel?: Channel;
-	cancel: Function;
+	cancel: (id?: string) => unknown;
 }
 
 export interface ListenEventOpts {
@@ -80,17 +81,18 @@ export interface ProcessEvent {
 
 export async function listenEvent(
 	event: string,
-	callback: (event: EventOpts) => any,
+	callback: (event: EventOpts) => unknown,
 	opts?: ListenEventOpts,
 ) {
 	if (RabbitMQ.connection) {
-		return await rabbitListen(
-			// @ts-ignore
-			opts?.channel || RabbitMQ.channel,
-			event,
-			callback,
-			{ acknowledge: opts?.acknowledge },
-		);
+		const channel = opts?.channel || RabbitMQ.channel;
+		if (!channel)
+			throw new Error(
+				"[Events] An event was sent without an associated channel",
+			);
+		return await rabbitListen(channel, event, callback, {
+			acknowledge: opts?.acknowledge,
+		});
 	} else if (process.env.EVENT_TRANSMISSION === "process") {
 		const cancel = async () => {
 			process.removeListener("message", listener);
@@ -103,13 +105,13 @@ export async function listenEvent(
 				callback({ ...msg.event, cancel });
 		};
 
-		//@ts-ignore apparently theres no function addListener with this signature
-		process.addListener("message", listener);
+		// TODO: assert the type is correct?
+		process.addListener("message", (msg) => listener(msg as ProcessEvent));
 		process.setMaxListeners(process.getMaxListeners() + 1);
 
 		return cancel;
 	} else {
-		const listener = (opts: any) => callback({ ...opts, cancel });
+		const listener = (opts: EventOpts) => callback({ ...opts, cancel });
 		const cancel = async () => {
 			events.removeListener(event, listener);
 			events.setMaxListeners(events.getMaxListeners() - 1);
@@ -124,7 +126,7 @@ export async function listenEvent(
 async function rabbitListen(
 	channel: Channel,
 	id: string,
-	callback: (event: EventOpts) => any,
+	callback: (event: EventOpts) => unknown,
 	opts?: { acknowledge?: boolean },
 ) {
 	await channel.assertExchange(id, "fanout", { durable: false });
diff --git a/src/util/util/FieldError.ts b/src/util/util/FieldError.ts
index 69df6f8e..eff793a8 100644
--- a/src/util/util/FieldError.ts
+++ b/src/util/util/FieldError.ts
@@ -42,7 +42,7 @@ export class FieldError extends Error {
 	constructor(
 		public code: string | number,
 		public message: string,
-		public errors?: any,
+		public errors?: object, // TODO: I don't like this typing.
 	) {
 		super(message);
 	}
diff --git a/src/util/util/Permissions.ts b/src/util/util/Permissions.ts
index 19614640..996c72ea 100644
--- a/src/util/util/Permissions.ts
+++ b/src/util/util/Permissions.ts
@@ -12,14 +12,7 @@ import {
 import { BitField } from "./BitField";
 import "missing-native-js-functions";
 import { BitFieldResolvable, BitFlag } from "./BitField";
-
-var HTTPError: any;
-
-try {
-	HTTPError = require("lambert-server").HTTPError;
-} catch (e) {
-	HTTPError = Error;
-}
+import { HTTPError } from "lambert-server";
 
 export type PermissionResolvable =
 	| bigint
@@ -31,7 +24,7 @@ export type PermissionResolvable =
 type PermissionString = keyof typeof Permissions.FLAGS;
 
 // BigInt doesn't have a bit limit (https://stackoverflow.com/questions/53335545/whats-the-biggest-bigint-value-in-js-as-per-spec)
-const CUSTOM_PERMISSION_OFFSET = BigInt(1) << BigInt(64); // 27 permission bits left for discord to add new ones
+// const CUSTOM_PERMISSION_OFFSET = BigInt(1) << BigInt(64); // 27 permission bits left for discord to add new ones
 
 export class Permissions extends BitField {
 	cache: PermissionCache = {};
@@ -114,7 +107,6 @@ export class Permissions extends BitField {
 	 */
 	hasThrow(permission: PermissionResolvable) {
 		if (this.has(permission) && this.has("VIEW_CHANNEL")) return true;
-		// @ts-ignore
 		throw new HTTPError(
 			`You are missing the following permissions ${permission}`,
 			403,
@@ -177,11 +169,11 @@ export class Permissions extends BitField {
 	}) {
 		if (user.id === "0") return new Permissions("ADMINISTRATOR"); // system user id
 
-		let roles = guild.roles.filter((x) => user.roles.includes(x.id));
+		const roles = guild.roles.filter((x) => user.roles.includes(x.id));
 		let permission = Permissions.rolePermission(roles);
 
 		if (channel?.overwrites) {
-			let overwrites = channel.overwrites.filter((x) => {
+			const overwrites = channel.overwrites.filter((x) => {
 				if (x.type === 0 && user.roles.includes(x.id)) return true;
 				if (x.type === 1 && x.id == user.id) return true;
 				return false;
@@ -244,9 +236,9 @@ export async function getPermission(
 	} = {},
 ) {
 	if (!user_id) throw new HTTPError("User not found");
-	var channel: Channel | undefined;
-	var member: Member | undefined;
-	var guild: Guild | undefined;
+	let channel: Channel | undefined;
+	let member: Member | undefined;
+	let guild: Guild | undefined;
 
 	if (channel_id) {
 		channel = await Channel.findOneOrFail({
@@ -258,7 +250,6 @@ export async function getPermission(
 				"permission_overwrites",
 				"owner_id",
 				"guild_id",
-				// @ts-ignore
 				...(opts.channel_select || []),
 			],
 		});
@@ -268,12 +259,7 @@ export async function getPermission(
 	if (guild_id) {
 		guild = await Guild.findOneOrFail({
 			where: { id: guild_id },
-			select: [
-				"id",
-				"owner_id",
-				// @ts-ignore
-				...(opts.guild_select || []),
-			],
+			select: ["id", "owner_id", ...(opts.guild_select || [])],
 			relations: opts.guild_relations,
 		});
 		if (guild.owner_id === user_id)
@@ -285,17 +271,16 @@ export async function getPermission(
 			// select: [
 			// "id",		// TODO: Bug in typeorm? adding these selects breaks the query.
 			// "roles",
-			// @ts-ignore
 			// ...(opts.member_select || []),
 			// ],
 		});
 	}
 
-	let recipient_ids: any = channel?.recipients?.map((x) => x.user_id);
-	if (!recipient_ids?.length) recipient_ids = null;
+	let recipient_ids = channel?.recipients?.map((x) => x.user_id);
+	if (!recipient_ids?.length) recipient_ids = undefined;
 
 	// TODO: remove guild.roles and convert recipient_ids to recipients
-	var permission = Permissions.finalPermission({
+	const permission = Permissions.finalPermission({
 		user: {
 			id: user_id,
 			roles: member?.roles.map((x) => x.id) || [],
diff --git a/src/util/util/Rights.ts b/src/util/util/Rights.ts
index 4d437956..b48477ed 100644
--- a/src/util/util/Rights.ts
+++ b/src/util/util/Rights.ts
@@ -20,14 +20,7 @@ import { BitField } from "./BitField";
 import "missing-native-js-functions";
 import { BitFieldResolvable, BitFlag } from "./BitField";
 import { User } from "../entities";
-
-var HTTPError: any;
-
-try {
-	HTTPError = require("lambert-server").HTTPError;
-} catch (e) {
-	HTTPError = Error;
-}
+import { HTTPError } from "lambert-server";
 
 export type RightResolvable =
 	| bigint
@@ -118,7 +111,6 @@ export class Rights extends BitField {
 
 	hasThrow(permission: RightResolvable) {
 		if (this.has(permission)) return true;
-		// @ts-ignore
 		throw new HTTPError(
 			`You are missing the following rights ${permission}`,
 			403,
@@ -137,6 +129,6 @@ export async function getRights(
 		in_behalf?: (keyof User)[];
 	} = {} **/
 ) {
-	let user = await User.findOneOrFail({ where: { id: user_id } });
+	const user = await User.findOneOrFail({ where: { id: user_id } });
 	return new Rights(user.rights);
 }
diff --git a/src/util/util/Sentry.ts b/src/util/util/Sentry.ts
index b0eee169..e1248353 100644
--- a/src/util/util/Sentry.ts
+++ b/src/util/util/Sentry.ts
@@ -34,7 +34,7 @@ export const Sentry = {
 			Config.get().sentry;
 		if (!enabled) return;
 
-		if (!!SentryNode.getCurrentHub().getClient()) return; // we've already initialised sentry
+		if (SentryNode.getCurrentHub().getClient()) return; // we've already initialised sentry
 
 		console.log("[Sentry] Enabling sentry...");
 
@@ -60,7 +60,7 @@ export const Sentry = {
 			environment,
 		});
 
-		SentryNode.addGlobalEventProcessor((event, hint) => {
+		SentryNode.addGlobalEventProcessor((event) => {
 			if (event.transaction) {
 				// Rewrite things that look like IDs to `:id` for sentry
 				event.transaction = event.transaction
@@ -112,6 +112,8 @@ export const Sentry = {
 		errorHandlersUsed = true;
 
 		app.use(SentryNode.Handlers.errorHandler());
+		// The typings for this are broken?
+		// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
 		app.use(function onError(err: any, req: any, res: any, next: any) {
 			res.statusCode = 500;
 			res.end(res.sentry + "\n");
diff --git a/src/util/util/Snowflake.ts b/src/util/util/Snowflake.ts
index 65546958..93898fbb 100644
--- a/src/util/util/Snowflake.ts
+++ b/src/util/util/Snowflake.ts
@@ -1,3 +1,4 @@
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
 // @ts-nocheck
 import * as cluster from "cluster";
 
@@ -87,10 +88,10 @@ export class Snowflake {
 
 	static generateWorkerProcess() {
 		// worker process - returns a number
-		var time = BigInt(Date.now() - Snowflake.EPOCH) << BigInt(22);
-		var worker = Snowflake.workerId << 17n;
-		var process = Snowflake.processId << 12n;
-		var increment = Snowflake.INCREMENT++;
+		const time = BigInt(Date.now() - Snowflake.EPOCH) << BigInt(22);
+		const worker = Snowflake.workerId << 17n;
+		const process = Snowflake.processId << 12n;
+		const increment = Snowflake.INCREMENT++;
 		return BigInt(time | worker | process | increment);
 	}
 
diff --git a/src/util/util/String.ts b/src/util/util/String.ts
index 7addd49a..74fd0295 100644
--- a/src/util/util/String.ts
+++ b/src/util/util/String.ts
@@ -19,7 +19,6 @@
 import { SPECIAL_CHAR } from "./Regex";
 
 export function trimSpecial(str?: string): string {
-	// @ts-ignore
-	if (!str) return;
+	if (!str) return "";
 	return str.replace(SPECIAL_CHAR, "").trim();
 }
diff --git a/src/util/util/Token.ts b/src/util/util/Token.ts
index c00142bb..ca81eaaa 100644
--- a/src/util/util/Token.ts
+++ b/src/util/util/Token.ts
@@ -22,7 +22,15 @@ import { User } from "../entities";
 
 export const JWTOptions: VerifyOptions = { algorithms: ["HS256"] };
 
-export function checkToken(token: string, jwtSecret: string): Promise<any> {
+export type UserTokenData = {
+	user: User;
+	decoded: { id: string; iat: number };
+};
+
+export function checkToken(
+	token: string,
+	jwtSecret: string,
+): Promise<UserTokenData> {
 	return new Promise((res, rej) => {
 		token = token.replace("Bot ", "");
 		token = token.replace("Bearer ", "");
@@ -31,24 +39,35 @@ export function checkToken(token: string, jwtSecret: string): Promise<any> {
 		as we don't really have separate pathways for bots 
 		**/
 
-		jwt.verify(token, jwtSecret, JWTOptions, async (err, decoded: any) => {
+		jwt.verify(token, jwtSecret, JWTOptions, async (err, decoded) => {
 			if (err || !decoded) return rej("Invalid Token");
+			if (
+				typeof decoded == "string" ||
+				!("id" in decoded) ||
+				!decoded.iat
+			)
+				return rej("Invalid Token"); // will never happen, just for typings.
 
 			const user = await User.findOne({
 				where: { id: decoded.id },
 				select: ["data", "bot", "disabled", "deleted", "rights"],
 			});
+
 			if (!user) return rej("Invalid Token");
+
 			// we need to round it to seconds as it saved as seconds in jwt iat and valid_tokens_since is stored in milliseconds
 			if (
 				decoded.iat * 1000 <
 				new Date(user.data.valid_tokens_since).setSeconds(0, 0)
 			)
 				return rej("Invalid Token");
+
 			if (user.disabled) return rej("User disabled");
 			if (user.deleted) return rej("User not found");
 
-			return res({ decoded, user });
+			// Using as here because we assert `id` and `iat` are in decoded.
+			// TS just doesn't want to assume its there, though.
+			return res({ decoded, user } as UserTokenData);
 		});
 	});
 }
diff --git a/src/util/util/TraverseDirectory.ts b/src/util/util/TraverseDirectory.ts
index 0cc48d4a..223e3ee0 100644
--- a/src/util/util/TraverseDirectory.ts
+++ b/src/util/util/TraverseDirectory.ts
@@ -22,7 +22,7 @@ import { Server, traverseDirectory } from "lambert-server";
 const extension =
 	Symbol.for("ts-node.register.instance") in process ? "ts" : "js";
 
-const DEFAULT_FILTER = new RegExp("^([^.].*)(?<!\.d).(" + extension + ")$");
+const DEFAULT_FILTER = new RegExp("^([^.].*)(?<!\\.d).(" + extension + ")$");
 
 export function registerRoutes(server: Server, root: string) {
 	return traverseDirectory(
diff --git a/src/util/util/cdn.ts b/src/util/util/cdn.ts
index 6d2fd0f1..7f447c53 100644
--- a/src/util/util/cdn.ts
+++ b/src/util/util/cdn.ts
@@ -24,7 +24,8 @@ import { Config } from "./Config";
 
 export async function uploadFile(
 	path: string,
-	file?: Express.Multer.File,
+	// These are the only props we use, don't need to enforce the full type.
+	file?: Pick<Express.Multer.File, "mimetype" | "originalname" | "buffer">,
 ): Promise<Attachment> {
 	if (!file?.buffer) throw new HTTPError("Missing file in body");
 
@@ -60,7 +61,6 @@ export async function handleFile(
 		const mimetype = body.split(":")[1].split(";")[0];
 		const buffer = Buffer.from(body.split(",")[1], "base64");
 
-		// @ts-ignore
 		const { id } = await uploadFile(path, {
 			buffer,
 			mimetype,