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,
|