summary refs log tree commit diff
path: root/src/util/entities
diff options
context:
space:
mode:
authorMadeline <46743919+MaddyUnderStars@users.noreply.github.com>2022-09-25 18:24:21 +1000
committerMadeline <46743919+MaddyUnderStars@users.noreply.github.com>2022-09-25 23:35:18 +1000
commitf44f5d7ac2d24ff836c2e1d4b2fa58da04b13052 (patch)
treea6655c41bb3db79c30fd876b06ee60fe9cf70c9b /src/util/entities
parentAllow edited_timestamp to passthrough in handleMessage (diff)
downloadserver-f44f5d7ac2d24ff836c2e1d4b2fa58da04b13052.tar.xz
Refactor to mono-repo + upgrade packages
Diffstat (limited to '')
-rw-r--r--src/util/entities/Application.ts (renamed from util/src/entities/Application.ts)0
-rw-r--r--src/util/entities/Attachment.ts (renamed from util/src/entities/Attachment.ts)0
-rw-r--r--src/util/entities/AuditLog.ts (renamed from util/src/entities/AuditLog.ts)0
-rw-r--r--src/util/entities/BackupCodes.ts (renamed from util/src/entities/BackupCodes.ts)0
-rw-r--r--src/util/entities/Ban.ts (renamed from util/src/entities/Ban.ts)0
-rw-r--r--src/util/entities/BaseClass.ts52
-rw-r--r--src/util/entities/Categories.ts (renamed from util/src/entities/Categories.ts)0
-rw-r--r--src/util/entities/Channel.ts (renamed from util/src/entities/Channel.ts)18
-rw-r--r--src/util/entities/ClientRelease.ts (renamed from util/src/entities/ClientRelease.ts)0
-rw-r--r--src/util/entities/Config.ts (renamed from util/src/entities/Config.ts)0
-rw-r--r--src/util/entities/ConnectedAccount.ts (renamed from util/src/entities/ConnectedAccount.ts)0
-rw-r--r--src/util/entities/Emoji.ts (renamed from util/src/entities/Emoji.ts)0
-rw-r--r--src/util/entities/Encryption.ts (renamed from util/src/entities/Encryption.ts)24
-rw-r--r--src/util/entities/Guild.ts (renamed from util/src/entities/Guild.ts)12
-rw-r--r--src/util/entities/Invite.ts (renamed from util/src/entities/Invite.ts)4
-rw-r--r--src/util/entities/Member.ts (renamed from util/src/entities/Member.ts)56
-rw-r--r--src/util/entities/Message.ts (renamed from util/src/entities/Message.ts)29
-rw-r--r--src/util/entities/Migration.ts (renamed from util/src/entities/Migration.ts)0
-rw-r--r--src/util/entities/Note.ts (renamed from util/src/entities/Note.ts)0
-rw-r--r--src/util/entities/RateLimit.ts (renamed from util/src/entities/RateLimit.ts)0
-rw-r--r--src/util/entities/ReadState.ts (renamed from util/src/entities/ReadState.ts)0
-rw-r--r--src/util/entities/Recipient.ts (renamed from util/src/entities/Recipient.ts)0
-rw-r--r--src/util/entities/Relationship.ts (renamed from util/src/entities/Relationship.ts)0
-rw-r--r--src/util/entities/Role.ts (renamed from util/src/entities/Role.ts)4
-rw-r--r--src/util/entities/Session.ts (renamed from util/src/entities/Session.ts)0
-rw-r--r--src/util/entities/Sticker.ts (renamed from util/src/entities/Sticker.ts)0
-rw-r--r--src/util/entities/StickerPack.ts (renamed from util/src/entities/StickerPack.ts)0
-rw-r--r--src/util/entities/Team.ts (renamed from util/src/entities/Team.ts)0
-rw-r--r--src/util/entities/TeamMember.ts (renamed from util/src/entities/TeamMember.ts)0
-rw-r--r--src/util/entities/Template.ts (renamed from util/src/entities/Template.ts)0
-rw-r--r--src/util/entities/User.ts (renamed from util/src/entities/User.ts)59
-rw-r--r--src/util/entities/VoiceState.ts (renamed from util/src/entities/VoiceState.ts)0
-rw-r--r--src/util/entities/Webhook.ts (renamed from util/src/entities/Webhook.ts)0
-rw-r--r--src/util/entities/index.ts (renamed from util/src/entities/index.ts)0
34 files changed, 159 insertions, 99 deletions
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/src/util/entities/BaseClass.ts b/src/util/entities/BaseClass.ts new file mode 100644
index 00000000..d5a7c2bf --- /dev/null +++ b/src/util/entities/BaseClass.ts
@@ -0,0 +1,52 @@ +import "reflect-metadata"; +import { BaseEntity, BeforeInsert, BeforeUpdate, FindOptionsWhere, ObjectIdColumn, PrimaryColumn } from "typeorm"; +import { Snowflake } from "../util/Snowflake"; +import "missing-native-js-functions"; +import { getDatabase } from ".."; +import { OrmUtils } from "@fosscord/util"; + +export class BaseClassWithoutId extends BaseEntity { + private get construct(): any { + return this.constructor; + } + + private get metadata() { + return getDatabase()?.getMetadata(this.construct); + } + + assign(props: any) { + OrmUtils.mergeDeep(this, props); + return this; + } + + 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: FindOptionsWhere<T>, propertyPath: string, value: number | string) { + const repository = this.getRepository(); + return repository.increment(conditions, propertyPath, value); + } + + static decrement<T extends BaseClass>(conditions: FindOptionsWhere<T>, propertyPath: string, value: number | string) { + const repository = this.getRepository(); + return repository.decrement(conditions, propertyPath, value); + } +} + +export const PrimaryIdColumn = process.env.DATABASE?.startsWith("mongodb") ? ObjectIdColumn : PrimaryColumn; + +export class BaseClass extends BaseClassWithoutId { + @PrimaryIdColumn() + id: string; + + @BeforeUpdate() + @BeforeInsert() + do_validate() { + if (!this.id) this.id = Snowflake.generate(); + } +} 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