diff --git a/util/src/dtos/DmChannelDTO.ts b/src/util/dtos/DmChannelDTO.ts
index 226b2f9d..226b2f9d 100644
--- a/util/src/dtos/DmChannelDTO.ts
+++ b/src/util/dtos/DmChannelDTO.ts
diff --git a/util/src/dtos/UserDTO.ts b/src/util/dtos/UserDTO.ts
index ee2752a4..ee2752a4 100644
--- a/util/src/dtos/UserDTO.ts
+++ b/src/util/dtos/UserDTO.ts
diff --git a/util/src/dtos/index.ts b/src/util/dtos/index.ts
index 0e8f8459..0e8f8459 100644
--- a/util/src/dtos/index.ts
+++ b/src/util/dtos/index.ts
diff --git a/util/src/entities/Application.ts b/src/util/entities/Application.ts
index fab3d93f..fab3d93f 100644
--- a/util/src/entities/Application.ts
+++ b/src/util/entities/Application.ts
diff --git a/util/src/entities/Attachment.ts b/src/util/entities/Attachment.ts
index 7b4b17eb..7b4b17eb 100644
--- a/util/src/entities/Attachment.ts
+++ b/src/util/entities/Attachment.ts
diff --git a/util/src/entities/AuditLog.ts b/src/util/entities/AuditLog.ts
index b003e7ba..b003e7ba 100644
--- a/util/src/entities/AuditLog.ts
+++ b/src/util/entities/AuditLog.ts
diff --git a/util/src/entities/BackupCodes.ts b/src/util/entities/BackupCodes.ts
index d532a39a..d532a39a 100644
--- a/util/src/entities/BackupCodes.ts
+++ b/src/util/entities/BackupCodes.ts
diff --git a/util/src/entities/Ban.ts b/src/util/entities/Ban.ts
index 9504bd8e..9504bd8e 100644
--- a/util/src/entities/Ban.ts
+++ b/src/util/entities/Ban.ts
diff --git a/util/src/entities/Categories.ts b/src/util/entities/Categories.ts
index 81fbc303..81fbc303 100644
--- a/util/src/entities/Categories.ts
+++ b/src/util/entities/Categories.ts
diff --git a/util/src/entities/Channel.ts b/src/util/entities/Channel.ts
index 10fa03ff..577b627e 100644
--- a/util/src/entities/Channel.ts
+++ b/src/util/entities/Channel.ts
@@ -58,7 +58,7 @@ export class Channel extends BaseClass {
recipients?: Recipient[];
@Column({ nullable: true })
- last_message_id: string;
+ last_message_id?: string;
@Column({ nullable: true })
@RelationId((channel: Channel) => channel.guild)
@@ -81,7 +81,7 @@ export class Channel extends BaseClass {
// for group DMs and owned custom channel types
@Column({ nullable: true })
@RelationId((channel: Channel) => channel.owner)
- owner_id: string;
+ owner_id?: string;
@JoinColumn({ name: "owner_id" })
@ManyToOne(() => User)
@@ -169,7 +169,7 @@ export class Channel extends BaseClass {
}
if (!opts?.skipNameChecks) {
- const guild = await Guild.findOneOrFail({ id: channel.guild_id });
+ const guild = await Guild.findOneOrFail({ where: { id: channel.guild_id } });
if (!guild.features.includes("ALLOW_INVALID_CHANNEL_NAMES") && channel.name) {
for (var character of InvisibleCharacters)
if (channel.name.includes(character))
@@ -202,7 +202,7 @@ export class Channel extends BaseClass {
case ChannelType.GUILD_NEWS:
case ChannelType.GUILD_VOICE:
if (channel.parent_id && !opts?.skipExistsCheck) {
- const exists = await Channel.findOneOrFail({ id: channel.parent_id });
+ const exists = await Channel.findOneOrFail({ where: { id: channel.parent_id } });
if (!exists) throw new HTTPError("Parent id channel doesn't exist", 400);
if (exists.guild_id !== channel.guild_id)
throw new HTTPError("The category channel needs to be in the guild");
@@ -230,7 +230,7 @@ export class Channel extends BaseClass {
};
await Promise.all([
- new Channel(channel).save(),
+ Channel.create(channel).save(),
!opts?.skipEventEmit
? emitEvent({
event: "CHANNEL_CREATE",
@@ -281,15 +281,15 @@ export class Channel extends BaseClass {
if (channel == null) {
name = trimSpecial(name);
- channel = await new Channel({
+ channel = await Channel.create({
name,
type,
- owner_id: type === ChannelType.DM ? undefined : null, // 1:1 DMs are ownerless in fosscord-server
+ owner_id: undefined,
created_at: new Date(),
- last_message_id: null,
+ last_message_id: undefined,
recipients: channelRecipients.map(
(x) =>
- new Recipient({ user_id: x, closed: !(type === ChannelType.GROUP_DM || x === creator_user_id) })
+ Recipient.create({ user_id: x, closed: !(type === ChannelType.GROUP_DM || x === creator_user_id) })
),
nsfw: false,
}).save();
diff --git a/util/src/entities/ClientRelease.ts b/src/util/entities/ClientRelease.ts
index c5afd307..c5afd307 100644
--- a/util/src/entities/ClientRelease.ts
+++ b/src/util/entities/ClientRelease.ts
diff --git a/util/src/entities/Config.ts b/src/util/entities/Config.ts
index 9aabc1a8..9aabc1a8 100644
--- a/util/src/entities/Config.ts
+++ b/src/util/entities/Config.ts
diff --git a/util/src/entities/ConnectedAccount.ts b/src/util/entities/ConnectedAccount.ts
index 09ae30ab..09ae30ab 100644
--- a/util/src/entities/ConnectedAccount.ts
+++ b/src/util/entities/ConnectedAccount.ts
diff --git a/util/src/entities/Emoji.ts b/src/util/entities/Emoji.ts
index a3615b7d..a3615b7d 100644
--- a/util/src/entities/Emoji.ts
+++ b/src/util/entities/Emoji.ts
diff --git a/util/src/entities/Encryption.ts b/src/util/entities/Encryption.ts
index 3b82ff84..b597b90a 100644
--- a/util/src/entities/Encryption.ts
+++ b/src/util/entities/Encryption.ts
@@ -14,22 +14,22 @@ import { DmChannelDTO } from "../dtos";
@Entity("security_settings")
export class SecuritySettings extends BaseClass {
- @Column({nullable: true})
- guild_id: Snowflake;
+ @Column({ nullable: true })
+ guild_id: string;
- @Column({nullable: true})
- channel_id: Snowflake;
+ @Column({ nullable: true })
+ channel_id: string;
- @Column()
- encryption_permission_mask: BitField;
+ @Column()
+ encryption_permission_mask: number;
- @Column()
- allowed_algorithms: string[];
+ @Column({ type: "simple-array" })
+ allowed_algorithms: string[];
- @Column()
- current_algorithm: string;
+ @Column()
+ current_algorithm: string;
- @Column({nullable: true})
- used_since_message: Snowflake;
+ @Column({ nullable: true })
+ used_since_message: string;
}
diff --git a/util/src/entities/Guild.ts b/src/util/entities/Guild.ts
index 143cb542..2ce7c213 100644
--- a/util/src/entities/Guild.ts
+++ b/src/util/entities/Guild.ts
@@ -86,7 +86,7 @@ export class Guild extends BaseClass {
//TODO: https://discord.com/developers/docs/resources/guild#guild-object-guild-features
@Column({ nullable: true })
- primary_category_id: number;
+ primary_category_id?: string; // TODO: this was number?
@Column({ nullable: true })
icon?: string;
@@ -285,7 +285,7 @@ export class Guild extends BaseClass {
}) {
const guild_id = Snowflake.generate();
- const guild = await new Guild({
+ const guild = await Guild.create({
name: body.name || "Fosscord",
icon: await handleFile(`/icons/${guild_id}`, body.icon as string),
region: Config.get().regions.default,
@@ -294,7 +294,7 @@ export class Guild extends BaseClass {
default_message_notifications: 1, // defaults effect: setting the push default at mentions-only will save a lot
explicit_content_filter: 0,
features: Config.get().guild.defaultFeatures,
- primary_category_id: null,
+ primary_category_id: undefined,
id: guild_id,
max_members: 250000,
max_presences: 250000,
@@ -320,7 +320,7 @@ export class Guild extends BaseClass {
// we have to create the role _after_ the guild because else we would get a "SQLITE_CONSTRAINT: FOREIGN KEY constraint failed" error
// TODO: make the @everyone a pseudorole that is dynamically generated at runtime so we can save storage
- await new Role({
+ await Role.create({
id: guild_id,
guild_id: guild_id,
color: 0,
@@ -331,8 +331,8 @@ export class Guild extends BaseClass {
name: "@everyone",
permissions: String("2251804225"),
position: 0,
- icon: null,
- unicode_emoji: null
+ icon: undefined,
+ unicode_emoji: undefined
}).save();
if (!body.channels || !body.channels.length) body.channels = [{ id: "01", type: 0, name: "general", nsfw: false }];
diff --git a/util/src/entities/Invite.ts b/src/util/entities/Invite.ts
index 6ac64ddc..4f36f247 100644
--- a/util/src/entities/Invite.ts
+++ b/src/util/entities/Invite.ts
@@ -52,7 +52,7 @@ export class Invite extends BaseClassWithoutId {
@Column({ nullable: true })
@RelationId((invite: Invite) => invite.inviter)
- inviter_id: string;
+ inviter_id?: string;
@JoinColumn({ name: "inviter_id" })
@ManyToOne(() => User)
@@ -75,7 +75,7 @@ export class Invite extends BaseClassWithoutId {
vanity_url?: boolean;
static async joinGuild(user_id: string, code: string) {
- const invite = await Invite.findOneOrFail({ code });
+ const invite = await Invite.findOneOrFail({ where: { code } });
if (invite.uses++ >= invite.max_uses && invite.max_uses !== 0) await Invite.delete({ code });
else await invite.save();
diff --git a/util/src/entities/Member.ts b/src/util/entities/Member.ts
index 03698453..d7bcefea 100644
--- a/util/src/entities/Member.ts
+++ b/src/util/entities/Member.ts
@@ -1,6 +1,8 @@
import { PublicUser, User } from "./User";
import { Message } from "./Message";
import {
+ BeforeInsert,
+ BeforeUpdate,
Column,
Entity,
Index,
@@ -73,17 +75,6 @@ export class Member extends BaseClassWithoutId {
@Column({ nullable: true })
nick?: string;
- setNick(val: string) {
-
- if (val) {
- val = val.split("\n").join("");
- val = val.split("\t").join("");
- if (BannedWords.find(val)) throw FieldErrors({ nick: { message: "Bad nickname", code: "INVALID_NICKNAME" } });
- }
-
- this.nick = val;
- }
-
@JoinTable({
name: "member_roles",
joinColumn: { name: "index", referencedColumnName: "index" },
@@ -129,8 +120,18 @@ export class Member extends BaseClassWithoutId {
// @Column({ type: "simple-json" })
// read_state: ReadState;
+ @BeforeUpdate()
+ @BeforeInsert()
+ validate() {
+ if (this.nick) {
+ this.nick = this.nick.split("\n").join("");
+ this.nick = this.nick.split("\t").join("");
+ if (BannedWords.find(this.nick)) throw FieldErrors({ nick: { message: "Bad nickname", code: "INVALID_NICKNAME" } });
+ }
+ }
+
static async IsInGuildOrFail(user_id: string, guild_id: string) {
- if (await Member.count({ id: user_id, guild: { id: guild_id } })) return true;
+ if (await Member.count({ where: { id: user_id, guild: { id: guild_id } } })) return true;
throw new HTTPError("You are not member of this guild", 403);
}
@@ -168,11 +169,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
- select: ["index", "roles.id"],
+ //@ts-ignore
+ select: ["index", "roles.id"], // TODO fix type
}),
Role.findOneOrFail({ where: { id: role_id, guild_id }, select: ["id"] }),
]);
- member.roles.push(new Role({ id: role_id }));
+ member.roles.push(Role.create({ id: role_id }));
await Promise.all([
member.save(),
@@ -194,9 +196,10 @@ 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
- select: ["roles.id", "index"],
+ //@ts-ignore
+ select: ["roles.id", "index"], // TODO: fix type
}),
- await Role.findOneOrFail({ id: role_id, guild_id }),
+ await Role.findOneOrFail({ where: { id: role_id, guild_id } }),
]);
member.roles = member.roles.filter((x) => x.id == role_id);
@@ -246,7 +249,7 @@ export class Member extends BaseClassWithoutId {
throw DiscordApiErrors.USER_BANNED;
}
const { maxGuilds } = Config.get().limits.user;
- const guild_count = await Member.count({ id: user_id });
+ const guild_count = await Member.count({ where: { id: user_id } });
if (guild_count >= maxGuilds) {
throw new HTTPError(`You are at the ${maxGuilds} server limit.`, 403);
}
@@ -258,7 +261,7 @@ export class Member extends BaseClassWithoutId {
relations: [...PublicGuildRelations, "system_channel"],
});
- if (await Member.count({ id: user.id, guild: { id: guild_id } }))
+ if (await Member.count({ where: { id: user.id, guild: { id: guild_id } } }))
throw new HTTPError("You are already a member of this guild", 400);
const member = {
@@ -274,12 +277,18 @@ export class Member extends BaseClassWithoutId {
};
await Promise.all([
- new Member({
+ Member.create({
...member,
- roles: [new Role({ id: guild_id })],
+ roles: [Role.create({ id: guild_id })],
// read_state: {},
settings: {
- channel_overrides: [],
+ guild_id: null,
+ mute_config: null,
+ mute_scheduled_events: false,
+ flags: 0,
+ hide_muted_channels: false,
+ notify_highlights: 0,
+ channel_overrides: {},
message_notifications: 0,
mobile_push: true,
muted: false,
@@ -318,13 +327,12 @@ export class Member extends BaseClassWithoutId {
if (guild.system_channel_id) {
// send welcome message
- const message = new Message({
+ const message = Message.create({
type: 7,
guild_id: guild.id,
channel_id: guild.system_channel_id,
author: user,
timestamp: new Date(),
-
reactions: [],
attachments: [],
embeds: [],
@@ -385,7 +393,7 @@ export const DefaultUserGuildSettings: UserGuildSettings = {
suppress_roles: false,
version: 453, // ?
guild_id: null,
-}
+};
export interface MuteConfig {
end_time: number;
diff --git a/util/src/entities/Message.ts b/src/util/entities/Message.ts
index 6ea5c4aa..3a3dd5e4 100644
--- a/util/src/entities/Message.ts
+++ b/src/util/entities/Message.ts
@@ -5,6 +5,8 @@ import { Channel } from "./Channel";
import { InteractionType } from "../interfaces/Interaction";
import { Application } from "./Application";
import {
+ BeforeInsert,
+ BeforeUpdate,
Column,
CreateDateColumn,
Entity,
@@ -23,6 +25,7 @@ import { Sticker } from "./Sticker";
import { Attachment } from "./Attachment";
import { BannedWords } from "../util";
import { HTTPError } from "lambert-server";
+import { ValidatorConstraint } from "class-validator";
export enum MessageType {
DEFAULT = 0,
@@ -58,7 +61,7 @@ export class Message extends BaseClass {
@Column({ nullable: true })
@RelationId((message: Message) => message.channel)
@Index()
- channel_id: string;
+ channel_id?: string;
@JoinColumn({ name: "channel_id" })
@ManyToOne(() => Channel, {
@@ -79,7 +82,7 @@ export class Message extends BaseClass {
@Column({ nullable: true })
@RelationId((message: Message) => message.author)
@Index()
- author_id: string;
+ author_id?: string;
@JoinColumn({ name: "author_id", referencedColumnName: "id" })
@ManyToOne(() => User, {
@@ -89,7 +92,7 @@ export class Message extends BaseClass {
@Column({ nullable: true })
@RelationId((message: Message) => message.member)
- member_id: string;
+ member_id?: string;
@JoinColumn({ name: "member_id", referencedColumnName: "id" })
@ManyToOne(() => User, {
@@ -99,7 +102,7 @@ export class Message extends BaseClass {
@Column({ nullable: true })
@RelationId((message: Message) => message.webhook)
- webhook_id: string;
+ webhook_id?: string;
@JoinColumn({ name: "webhook_id" })
@ManyToOne(() => Webhook)
@@ -107,7 +110,7 @@ export class Message extends BaseClass {
@Column({ nullable: true })
@RelationId((message: Message) => message.application)
- application_id: string;
+ application_id?: string;
@JoinColumn({ name: "application_id" })
@ManyToOne(() => Application)
@@ -116,17 +119,12 @@ export class Message extends BaseClass {
@Column({ nullable: true, type: process.env.PRODUCTION ? "longtext" : undefined })
content?: string;
- setContent(val: string) {
- if (val && BannedWords.find(val)) throw new HTTPError("Message was blocked by automatic moderation", 200000);
- this.content = val;
- }
-
@Column()
@CreateDateColumn()
timestamp: Date;
@Column({ nullable: true })
- edited_timestamp: Date;
+ edited_timestamp?: Date;
@Column({ nullable: true })
tts?: boolean;
@@ -179,6 +177,7 @@ export class Message extends BaseClass {
@Column({ nullable: true })
flags?: string;
+
@Column({ type: "simple-json", nullable: true })
message_reference?: {
message_id: string;
@@ -201,6 +200,14 @@ export class Message extends BaseClass {
@Column({ type: "simple-json", nullable: true })
components?: MessageComponent[];
+
+ @BeforeUpdate()
+ @BeforeInsert()
+ validate() {
+ if (this.content) {
+ if (BannedWords.find(this.content)) throw new HTTPError("Message was blocked by automatic moderation", 200000);
+ }
+ }
}
export interface MessageComponent {
diff --git a/util/src/entities/Migration.ts b/src/util/entities/Migration.ts
index 3f39ae72..3f39ae72 100644
--- a/util/src/entities/Migration.ts
+++ b/src/util/entities/Migration.ts
diff --git a/util/src/entities/Note.ts b/src/util/entities/Note.ts
index 36017c5e..36017c5e 100644
--- a/util/src/entities/Note.ts
+++ b/src/util/entities/Note.ts
diff --git a/util/src/entities/RateLimit.ts b/src/util/entities/RateLimit.ts
index f5916f6b..f5916f6b 100644
--- a/util/src/entities/RateLimit.ts
+++ b/src/util/entities/RateLimit.ts
diff --git a/util/src/entities/ReadState.ts b/src/util/entities/ReadState.ts
index b915573b..b915573b 100644
--- a/util/src/entities/ReadState.ts
+++ b/src/util/entities/ReadState.ts
diff --git a/util/src/entities/Recipient.ts b/src/util/entities/Recipient.ts
index a945f938..a945f938 100644
--- a/util/src/entities/Recipient.ts
+++ b/src/util/entities/Recipient.ts
diff --git a/util/src/entities/Relationship.ts b/src/util/entities/Relationship.ts
index c3592c76..c3592c76 100644
--- a/util/src/entities/Relationship.ts
+++ b/src/util/entities/Relationship.ts
diff --git a/util/src/entities/Role.ts b/src/util/entities/Role.ts
index 4b721b5b..d87b835f 100644
--- a/util/src/entities/Role.ts
+++ b/src/util/entities/Role.ts
@@ -37,10 +37,10 @@ export class Role extends BaseClass {
position: number;
@Column({ nullable: true })
- icon: string;
+ icon?: string;
@Column({ nullable: true })
- unicode_emoji: string;
+ unicode_emoji?: string;
@Column({ type: "simple-json", nullable: true })
tags?: {
diff --git a/util/src/entities/Session.ts b/src/util/entities/Session.ts
index 969efa89..969efa89 100644
--- a/util/src/entities/Session.ts
+++ b/src/util/entities/Session.ts
diff --git a/util/src/entities/Sticker.ts b/src/util/entities/Sticker.ts
index 37bc6fbe..37bc6fbe 100644
--- a/util/src/entities/Sticker.ts
+++ b/src/util/entities/Sticker.ts
diff --git a/util/src/entities/StickerPack.ts b/src/util/entities/StickerPack.ts
index ec8c69a2..ec8c69a2 100644
--- a/util/src/entities/StickerPack.ts
+++ b/src/util/entities/StickerPack.ts
diff --git a/util/src/entities/Team.ts b/src/util/entities/Team.ts
index 22140b7f..22140b7f 100644
--- a/util/src/entities/Team.ts
+++ b/src/util/entities/Team.ts
diff --git a/util/src/entities/TeamMember.ts b/src/util/entities/TeamMember.ts
index b726e1e8..b726e1e8 100644
--- a/util/src/entities/TeamMember.ts
+++ b/src/util/entities/TeamMember.ts
diff --git a/util/src/entities/Template.ts b/src/util/entities/Template.ts
index 1d952283..1d952283 100644
--- a/util/src/entities/Template.ts
+++ b/src/util/entities/Template.ts
diff --git a/util/src/entities/User.ts b/src/util/entities/User.ts
index 35aeea52..84a8a674 100644
--- a/util/src/entities/User.ts
+++ b/src/util/entities/User.ts
@@ -1,4 +1,4 @@
-import { Column, Entity, FindOneOptions, JoinColumn, OneToMany } from "typeorm";
+import { BeforeInsert, BeforeUpdate, Column, Entity, FindOneOptions, JoinColumn, OneToMany } from "typeorm";
import { BaseClass } from "./BaseClass";
import { BitField } from "../util/BitField";
import { Relationship } from "./Relationship";
@@ -59,23 +59,9 @@ export class User extends BaseClass {
@Column()
username: string; // username max length 32, min 2 (should be configurable)
- setUsername(val: string) {
- if (BannedWords.find(val)) throw FieldErrors({ username: { message: "Bad username", code: "INVALID_USERNAME" } });
- this.username = val;
- }
-
@Column()
discriminator: string; // opaque string: 4 digits on discord.com
- setDiscriminator(val: string) {
- const number = Number(val);
- if (val.length > 4) throw new Error("invalid discriminator");
- if (isNaN(number)) throw new Error("invalid discriminator");
- if (number <= 0 || number >= 10000) throw new Error("discriminator must be between 1 and 9999");
- val = Number(val).toString();
- this.discriminator = val.toString().padStart(4, "0");
- }
-
@Column({ nullable: true })
avatar?: string; // hash of the user avatar
@@ -139,13 +125,6 @@ export class User extends BaseClass {
@Column({ nullable: true, select: false })
email?: string; // email of the user
- setEmail(val?: string) {
- val = adjustEmail(val);
- if (!val) throw FieldErrors({ email: { message: "Invalid email", code: "EMAIL_INVALID" } });
- if (!val.match(/([a-z\d.-]{3,})@([a-z\d.-]+).([a-z]{2,})/g)) throw FieldErrors({ email: { message: "Invalid email", code: "EMAIL_INVALID" } });
- this.email = val;
- }
-
@Column()
flags: string; // UserFlags
@@ -194,6 +173,22 @@ export class User extends BaseClass {
@Column({ type: "simple-json", select: false })
extended_settings: string;
+ @BeforeUpdate()
+ @BeforeInsert()
+ validate() {
+ this.email = adjustEmail(this.email);
+ if (!this.email) throw FieldErrors({ email: { message: "Invalid email", code: "EMAIL_INVALID" } });
+ if (!this.email.match(/([a-z\d.-]{3,})@([a-z\d.-]+).([a-z]{2,})/g)) throw FieldErrors({ email: { message: "Invalid email", code: "EMAIL_INVALID" } });
+
+ const discrim = Number(this.discriminator);
+ if (this.discriminator.length > 4) throw FieldErrors({ email: { message: "Discriminator cannot be more than 4 digits.", code: "DISCRIMINATOR_INVALID" } });
+ if (isNaN(discrim)) throw FieldErrors({ email: { message: "Discriminator must be a number.", code: "DISCRIMINATOR_INVALID" } });
+ if (discrim <= 0 || discrim >= 10000) throw FieldErrors({ email: { message: "Discriminator must be a number.", code: "DISCRIMINATOR_INVALID" } });
+ this.discriminator = discrim.toString().padStart(4, "0");
+
+ if (BannedWords.find(this.username)) throw FieldErrors({ username: { message: "Bad username", code: "INVALID_USERNAME" } });
+ }
+
toPublicUser() {
const user: any = {};
PublicUserProjection.forEach((x) => {
@@ -203,13 +198,12 @@ export class User extends BaseClass {
}
static async getPublicUser(user_id: string, opts?: FindOneOptions<User>) {
- return await User.findOneOrFail(
- { id: user_id },
- {
- ...opts,
- select: [...PublicUserProjection, ...(opts?.select || [])],
- }
- );
+ return await User.findOneOrFail({
+ where: { id: user_id },
+ ...opts,
+ //@ts-ignore
+ select: [...PublicUserProjection, ...(opts?.select || [])], // TODO: fix
+ });
}
private static async generateDiscriminator(username: string): Promise<string | undefined> {
@@ -273,7 +267,7 @@ export class User extends BaseClass {
// 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";
- const user = new User({
+ const user = User.create({
created_at: new Date(),
username: username,
discriminator,
@@ -293,7 +287,7 @@ export class User extends BaseClass {
email: email,
rights: Config.get().security.defaultRights,
nsfw_allowed: true, // TODO: depending on age
- public_flags: "0",
+ public_flags: 0,
flags: "0", // TODO: generate
data: {
hash: password,
@@ -302,9 +296,8 @@ export class User extends BaseClass {
settings: { ...defaultSettings, locale: language },
purchased_flags: 5, // TODO: idk what the values for this are
premium_usage_flags: 2, // TODO: idk what the values for this are
- extended_settings: {},
+ extended_settings: "", // TODO: was {}
fingerprints: [],
- notes: {},
});
await user.save();
diff --git a/util/src/entities/VoiceState.ts b/src/util/entities/VoiceState.ts
index 75748a01..75748a01 100644
--- a/util/src/entities/VoiceState.ts
+++ b/src/util/entities/VoiceState.ts
diff --git a/util/src/entities/Webhook.ts b/src/util/entities/Webhook.ts
index 89538417..89538417 100644
--- a/util/src/entities/Webhook.ts
+++ b/src/util/entities/Webhook.ts
diff --git a/util/src/entities/index.ts b/src/util/entities/index.ts
index 49793810..49793810 100644
--- a/util/src/entities/index.ts
+++ b/src/util/entities/index.ts
diff --git a/util/src/index.ts b/src/util/index.ts
index 52117302..385070a3 100644
--- a/util/src/index.ts
+++ b/src/util/index.ts
@@ -4,4 +4,5 @@ export * from "./util/index";
export * from "./interfaces/index";
export * from "./entities/index";
export * from "./dtos/index";
-export * from "./schemas";
\ No newline at end of file
+export * from "./schemas";
+export * from "./imports";
\ No newline at end of file
diff --git a/util/src/interfaces/Activity.ts b/src/util/interfaces/Activity.ts
index 9912e197..9912e197 100644
--- a/util/src/interfaces/Activity.ts
+++ b/src/util/interfaces/Activity.ts
diff --git a/util/src/interfaces/Event.ts b/src/util/interfaces/Event.ts
index 59f995db..59f995db 100644
--- a/util/src/interfaces/Event.ts
+++ b/src/util/interfaces/Event.ts
diff --git a/util/src/interfaces/Interaction.ts b/src/util/interfaces/Interaction.ts
index 5d3aae24..5d3aae24 100644
--- a/util/src/interfaces/Interaction.ts
+++ b/src/util/interfaces/Interaction.ts
diff --git a/util/src/interfaces/Presence.ts b/src/util/interfaces/Presence.ts
index 7663891a..7663891a 100644
--- a/util/src/interfaces/Presence.ts
+++ b/src/util/interfaces/Presence.ts
diff --git a/util/src/interfaces/Status.ts b/src/util/interfaces/Status.ts
index 5d2e1bba..5d2e1bba 100644
--- a/util/src/interfaces/Status.ts
+++ b/src/util/interfaces/Status.ts
diff --git a/util/src/interfaces/index.ts b/src/util/interfaces/index.ts
index ab7fa429..ab7fa429 100644
--- a/util/src/interfaces/index.ts
+++ b/src/util/interfaces/index.ts
diff --git a/util/src/migrations/1633864260873-EmojiRoles.ts b/src/util/migrations/1633864260873-EmojiRoles.ts
index f0d709f2..f0d709f2 100644
--- a/util/src/migrations/1633864260873-EmojiRoles.ts
+++ b/src/util/migrations/1633864260873-EmojiRoles.ts
diff --git a/util/src/migrations/1633864669243-EmojiUser.ts b/src/util/migrations/1633864669243-EmojiUser.ts
index 982405d7..982405d7 100644
--- a/util/src/migrations/1633864669243-EmojiUser.ts
+++ b/src/util/migrations/1633864669243-EmojiUser.ts
diff --git a/util/src/migrations/1633881705509-VanityInvite.ts b/src/util/migrations/1633881705509-VanityInvite.ts
index 45485310..45485310 100644
--- a/util/src/migrations/1633881705509-VanityInvite.ts
+++ b/src/util/migrations/1633881705509-VanityInvite.ts
diff --git a/util/src/migrations/1634308884591-Stickers.ts b/src/util/migrations/1634308884591-Stickers.ts
index fbc4649f..fbc4649f 100644
--- a/util/src/migrations/1634308884591-Stickers.ts
+++ b/src/util/migrations/1634308884591-Stickers.ts
diff --git a/util/src/migrations/1634424361103-Presence.ts b/src/util/migrations/1634424361103-Presence.ts
index 729955b8..729955b8 100644
--- a/util/src/migrations/1634424361103-Presence.ts
+++ b/src/util/migrations/1634424361103-Presence.ts
diff --git a/util/src/migrations/1634426540271-MigrationTimestamp.ts b/src/util/migrations/1634426540271-MigrationTimestamp.ts
index 3208b25b..3208b25b 100644
--- a/util/src/migrations/1634426540271-MigrationTimestamp.ts
+++ b/src/util/migrations/1634426540271-MigrationTimestamp.ts
diff --git a/util/src/migrations/1648643945733-ReleaseTypo.ts b/src/util/migrations/1648643945733-ReleaseTypo.ts
index 944b9dd9..944b9dd9 100644
--- a/util/src/migrations/1648643945733-ReleaseTypo.ts
+++ b/src/util/migrations/1648643945733-ReleaseTypo.ts
diff --git a/util/src/migrations/1660678870706-opencordFixes.ts b/src/util/migrations/1660678870706-opencordFixes.ts
index 1f10c212..1f10c212 100644
--- a/util/src/migrations/1660678870706-opencordFixes.ts
+++ b/src/util/migrations/1660678870706-opencordFixes.ts
diff --git a/util/src/migrations/1660689892073-mobileFixes2.ts b/src/util/migrations/1660689892073-mobileFixes2.ts
index bd28694e..bd28694e 100644
--- a/util/src/migrations/1660689892073-mobileFixes2.ts
+++ b/src/util/migrations/1660689892073-mobileFixes2.ts
diff --git a/util/src/schemas/Validator.ts b/src/util/schemas/Validator.ts
index e5f12ac5..b71bf6a1 100644
--- a/util/src/schemas/Validator.ts
+++ b/src/util/schemas/Validator.ts
@@ -3,7 +3,7 @@ import addFormats from "ajv-formats";
import fs from "fs";
import path from "path";
-const SchemaPath = path.join(__dirname, "..", "..", "..", "api", "assets", "schemas.json");
+const SchemaPath = path.join(__dirname, "..", "..", "..", "assets", "schemas.json");
const schemas = JSON.parse(fs.readFileSync(SchemaPath, { encoding: "utf8" }));
export const ajv = new Ajv({
diff --git a/util/src/schemas/index.ts b/src/util/schemas/index.ts
index 662152dc..662152dc 100644
--- a/util/src/schemas/index.ts
+++ b/src/util/schemas/index.ts
diff --git a/util/src/schemas/voice.ts b/src/util/schemas/voice.ts
index 61c12f92..61c12f92 100644
--- a/util/src/schemas/voice.ts
+++ b/src/util/schemas/voice.ts
diff --git a/util/src/util/ApiError.ts b/src/util/util/ApiError.ts
index f1a9b4f6..f1a9b4f6 100644
--- a/util/src/util/ApiError.ts
+++ b/src/util/util/ApiError.ts
diff --git a/util/src/util/Array.ts b/src/util/util/Array.ts
index 5a45d1b5..5a45d1b5 100644
--- a/util/src/util/Array.ts
+++ b/src/util/util/Array.ts
diff --git a/util/src/util/AutoUpdate.ts b/src/util/util/AutoUpdate.ts
index 531bd8b7..fd65ecf5 100644
--- a/util/src/util/AutoUpdate.ts
+++ b/src/util/util/AutoUpdate.ts
@@ -76,7 +76,7 @@ async function getLatestVersion(url: string) {
try {
const agent = new ProxyAgent();
const response = await fetch(url, { agent });
- const content = await response.json();
+ const content = await response.json() as any; // TODO: types
return content.version;
} catch (error) {
throw new Error("[Auto update] check failed for " + url);
diff --git a/util/src/util/BannedWords.ts b/src/util/util/BannedWords.ts
index 891a5980..891a5980 100644
--- a/util/src/util/BannedWords.ts
+++ b/src/util/util/BannedWords.ts
diff --git a/util/src/util/BitField.ts b/src/util/util/BitField.ts
index fb887e05..fb887e05 100644
--- a/util/src/util/BitField.ts
+++ b/src/util/util/BitField.ts
diff --git a/util/src/util/Categories.ts b/src/util/util/Categories.ts
index a3c69da7..a3c69da7 100644
--- a/util/src/util/Categories.ts
+++ b/src/util/util/Categories.ts
diff --git a/util/src/util/Config.ts b/src/util/util/Config.ts
index 31b8d97c..31b8d97c 100644
--- a/util/src/util/Config.ts
+++ b/src/util/util/Config.ts
diff --git a/util/src/util/Constants.ts b/src/util/util/Constants.ts
index 81a7165d..81a7165d 100644
--- a/util/src/util/Constants.ts
+++ b/src/util/util/Constants.ts
diff --git a/util/src/util/Email.ts b/src/util/util/Email.ts
index 6885da33..6885da33 100644
--- a/util/src/util/Email.ts
+++ b/src/util/util/Email.ts
diff --git a/util/src/util/Event.ts b/src/util/util/Event.ts
index 20a638a0..20a638a0 100644
--- a/util/src/util/Event.ts
+++ b/src/util/util/Event.ts
diff --git a/util/src/util/FieldError.ts b/src/util/util/FieldError.ts
index 406b33e8..406b33e8 100644
--- a/util/src/util/FieldError.ts
+++ b/src/util/util/FieldError.ts
diff --git a/util/src/util/Intents.ts b/src/util/util/Intents.ts
index 1e840b76..1e840b76 100644
--- a/util/src/util/Intents.ts
+++ b/src/util/util/Intents.ts
diff --git a/util/src/util/InvisibleCharacters.ts b/src/util/util/InvisibleCharacters.ts
index a48cfab0..a48cfab0 100644
--- a/util/src/util/InvisibleCharacters.ts
+++ b/src/util/util/InvisibleCharacters.ts
diff --git a/util/src/util/MessageFlags.ts b/src/util/util/MessageFlags.ts
index b59295c4..b59295c4 100644
--- a/util/src/util/MessageFlags.ts
+++ b/src/util/util/MessageFlags.ts
diff --git a/util/src/util/Permissions.ts b/src/util/util/Permissions.ts
index e5459ab5..e5459ab5 100644
--- a/util/src/util/Permissions.ts
+++ b/src/util/util/Permissions.ts
diff --git a/util/src/util/RabbitMQ.ts b/src/util/util/RabbitMQ.ts
index 0f5eb6aa..0f5eb6aa 100644
--- a/util/src/util/RabbitMQ.ts
+++ b/src/util/util/RabbitMQ.ts
diff --git a/util/src/util/Regex.ts b/src/util/util/Regex.ts
index 83fc9fe8..83fc9fe8 100644
--- a/util/src/util/Regex.ts
+++ b/src/util/util/Regex.ts
diff --git a/util/src/util/Rights.ts b/src/util/util/Rights.ts
index b28c75b7..b28c75b7 100644
--- a/util/src/util/Rights.ts
+++ b/src/util/util/Rights.ts
diff --git a/util/src/util/Snowflake.ts b/src/util/util/Snowflake.ts
index 134d526e..134d526e 100644
--- a/util/src/util/Snowflake.ts
+++ b/src/util/util/Snowflake.ts
diff --git a/util/src/util/String.ts b/src/util/util/String.ts
index 55f11e8d..55f11e8d 100644
--- a/util/src/util/String.ts
+++ b/src/util/util/String.ts
diff --git a/util/src/util/Token.ts b/src/util/util/Token.ts
index 500ace45..5ba3e1ec 100644
--- a/util/src/util/Token.ts
+++ b/src/util/util/Token.ts
@@ -11,14 +11,14 @@ export function checkToken(token: string, jwtSecret: string): Promise<any> {
in fosscord, even with instances that have bot distinction; we won't enforce "Bot" prefix,
as we don't really have separate pathways for bots
**/
-
+
jwt.verify(token, jwtSecret, JWTOptions, async (err, decoded: any) => {
if (err || !decoded) return rej("Invalid Token");
- const user = await User.findOne(
- { id: decoded.id },
- { select: ["data", "bot", "disabled", "deleted", "rights"] }
- );
+ 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))
diff --git a/util/src/util/TraverseDirectory.ts b/src/util/util/TraverseDirectory.ts
index 3d0d6279..3d0d6279 100644
--- a/util/src/util/TraverseDirectory.ts
+++ b/src/util/util/TraverseDirectory.ts
diff --git a/util/src/util/cdn.ts b/src/util/util/cdn.ts
index ea950cd1..812a4e1d 100644
--- a/util/src/util/cdn.ts
+++ b/src/util/util/cdn.ts
@@ -1,10 +1,10 @@
import FormData from "form-data";
import { HTTPError } from "lambert-server";
import fetch from "node-fetch";
+import { Attachment } from "../entities";
import { Config } from "./Config";
-import multer from "multer";
-export async function uploadFile(path: string, file?: Express.Multer.File) {
+export async function uploadFile(path: string, file?: Express.Multer.File): Promise<Attachment> {
if (!file?.buffer) throw new HTTPError("Missing file in body");
const form = new FormData();
@@ -21,7 +21,7 @@ export async function uploadFile(path: string, file?: Express.Multer.File) {
method: "POST",
body: form,
});
- const result = await response.json();
+ const result = await response.json() as Attachment;
if (response.status !== 200) throw result;
return result;
diff --git a/util/src/util/index.ts b/src/util/util/index.ts
index b2bd6489..b2bd6489 100644
--- a/util/src/util/index.ts
+++ b/src/util/util/index.ts
diff --git a/util/src/entities/BaseClass.ts b/util/src/entities/BaseClass.ts
deleted file mode 100644
index aabca016..00000000
--- a/util/src/entities/BaseClass.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import "reflect-metadata";
-import { BaseEntity, EntityMetadata, FindConditions, ObjectIdColumn, PrimaryColumn } from "typeorm";
-import { Snowflake } from "../util/Snowflake";
-import "missing-native-js-functions";
-
-export class BaseClassWithoutId extends BaseEntity {
- constructor(props?: any) {
- super();
- this.assign(props);
- }
-
- private get construct(): any {
- return this.constructor;
- }
-
- private get metadata() {
- return this.construct.getRepository().metadata as EntityMetadata;
- }
-
- assign(props: any = {}) {
- delete props.opts;
- delete props.props;
-
- const properties = new Set(
- this.metadata.columns
- .map((x: any) => x.propertyName)
- .concat(this.metadata.relations.map((x) => x.propertyName))
- );
- // will not include relational properties
-
- for (const key in props) {
- if (!properties.has(key)) continue;
- // @ts-ignore
- const setter = this[`set${key.capitalize()}`]; // use setter function if it exists
-
- if (setter) {
- setter.call(this, props[key]);
- } else {
- // @ts-ignore
- this[key] = props[key];
- }
- }
- }
-
- toJSON(): any {
- return Object.fromEntries(
- this.metadata.columns // @ts-ignore
- .map((x) => [x.propertyName, this[x.propertyName]]) // @ts-ignore
- .concat(this.metadata.relations.map((x) => [x.propertyName, this[x.propertyName]]))
- );
- }
-
- static increment<T extends BaseClass>(conditions: FindConditions<T>, propertyPath: string, value: number | string) {
- const repository = this.getRepository();
- return repository.increment(conditions as T, propertyPath, value);
- }
-
- static decrement<T extends BaseClass>(conditions: FindConditions<T>, propertyPath: string, value: number | string) {
- const repository = this.getRepository();
- return repository.decrement(conditions as T, propertyPath, value);
- }
-}
-
-export const PrimaryIdColumn = process.env.DATABASE?.startsWith("mongodb") ? ObjectIdColumn : PrimaryColumn;
-
-export class BaseClass extends BaseClassWithoutId {
- @PrimaryIdColumn()
- id: string;
-
- assign(props: any = {}) {
- super.assign(props);
- if (!this.id) this.id = Snowflake.generate();
- return this;
- }
-}
diff --git a/util/src/entities/Group.ts b/util/src/entities/Group.ts
deleted file mode 100644
index b24d38cf..00000000
--- a/util/src/entities/Group.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-
-import { BaseClass } from "./BaseClass";
-
-@Entity("groups")
-export class UserGroup extends BaseClass {
- @Column({ nullable: true })
- parent?: BigInt;
-
- @Column()
- color: number;
-
- @Column()
- hoist: boolean;
-
- @Column()
- mentionable: boolean;
-
- @Column()
- name: string;
-
- @Column()
- rights: BigInt;
-
- @Column()
- position: number;
-
- @Column({ nullable: true })
- icon: BigInt;
-
- @Column({ nullable: true })
- unicode_emoji: BigInt;
-}
diff --git a/util/src/entities/UserGroup.ts b/util/src/entities/UserGroup.ts
deleted file mode 100644
index 709b9d0b..00000000
--- a/util/src/entities/UserGroup.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-
-import { BaseClass } from "./BaseClass";
-import { Guild } from "./Guild";
-import { User } from "./User";
-
-@Entity("groups")
-export class UserGroup extends BaseClass {
- @Column()
- color: number;
-
- @Column()
- hoist: boolean;
-
- @JoinColumn({ name: "controller", referencedColumnName: "id" })
- @ManyToOne(() => User)
- controller?: User;
-
- @Column()
- mentionable_by?: string;
-
- @Column()
- name: string;
-
- @Column()
- rights: string;
-
- @Column({ nullable: true })
- icon: string;
-
- @Column({ nullable: true })
- parent?: string;
-
- @Column({ type: "simple-array", nullable: true})
- associciations: string[];
-
-}
diff --git a/util/src/util/Database.ts b/util/src/util/Database.ts
deleted file mode 100644
index 47d1987b..00000000
--- a/util/src/util/Database.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-import path from "path";
-import "reflect-metadata";
-import { Connection, createConnection } from "typeorm";
-import * as Models from "../entities";
-import { Migration } from "../entities/Migration";
-import { yellow, green, red } from "picocolors";
-
-// 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 promise: Promise<any>;
-var dbConnection: Connection | undefined;
-let dbConnectionString = process.env.DATABASE || path.join(process.cwd(), "database.db");
-
-export function initDatabase(): Promise<Connection> {
- if (promise) return promise; // prevent initalizing multiple times
-
- const type = dbConnectionString.includes("://") ? dbConnectionString.split(":")[0]?.replace("+srv", "") : "sqlite";
- const isSqlite = type.includes("sqlite");
-
- console.log(`[Database] ${yellow(`connecting to ${type} db`)}`);
- if(isSqlite) {
- console.log(`[Database] ${red(`You are running sqlite! Please keep in mind that we recommend setting up a dedicated database!`)}`);
- }
- // @ts-ignore
- promise = createConnection({
- type,
- charset: 'utf8mb4',
- url: isSqlite ? undefined : dbConnectionString,
- database: isSqlite ? dbConnectionString : undefined,
- // @ts-ignore
- entities: Object.values(Models).filter((x) => x?.constructor?.name !== "Object" && x?.name),
- synchronize: type !== "mongodb",
- logging: false,
- // cache: { // cache is used only by query builder and entity manager
- // duration: 1000 * 30,
- // type: "redis",
- // options: {
- // host: "localhost",
- // port: 6379,
- // },
- // },
- bigNumberStrings: false,
- supportBigNumbers: true,
- name: "default",
- migrations: [path.join(__dirname, "..", "migrations", "*.js")],
- });
-
- promise.then(async (connection: Connection) => {
- dbConnection = connection;
-
- // run migrations, and if it is a new fresh database, set it to the last migration
- if (connection.migrations.length) {
- if (!(await Migration.findOne({}))) {
- let i = 0;
-
- await Migration.insert(
- connection.migrations.map((x) => ({
- id: i++,
- name: x.name,
- timestamp: Date.now(),
- }))
- );
- }
- }
- await connection.runMigrations();
- console.log(`[Database] ${green("connected")}`);
- });
-
- return promise;
-}
-
-export { dbConnection };
-
-export function closeDatabase() {
- dbConnection?.close();
-}
|