From db3f5c0d1b5556e16c37704467b3599a6230be02 Mon Sep 17 00:00:00 2001 From: Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> Date: Thu, 26 Aug 2021 20:48:09 +0200 Subject: [PATCH] :sparkles: use RelationId --- util/src/entities/Application.ts | 6 +- util/src/entities/AuditLog.ts | 6 +- util/src/entities/Ban.ts | 8 +- util/src/entities/Channel.ts | 12 +- util/src/entities/Config.ts | 274 ++++++++++++++++++++++++++++++ util/src/entities/Emoji.ts | 4 +- util/src/entities/Guild.ts | 29 ++-- util/src/entities/Invite.ts | 12 +- util/src/entities/Member.ts | 6 +- util/src/entities/Message.ts | 29 ++-- util/src/entities/RateLimit.ts | 4 +- util/src/entities/ReadState.ts | 9 +- util/src/entities/Relationship.ts | 4 +- util/src/entities/Role.ts | 4 +- util/src/entities/Team.ts | 6 +- util/src/entities/TeamMember.ts | 6 +- util/src/entities/Template.ts | 8 +- util/src/entities/User.ts | 41 ++++- util/src/entities/VoiceState.ts | 11 +- util/src/entities/Webhook.ts | 46 +++-- util/src/entities/index.ts | 1 + 21 files changed, 444 insertions(+), 82 deletions(-) create mode 100644 util/src/entities/Config.ts diff --git a/util/src/entities/Application.ts b/util/src/entities/Application.ts index 64b5d2e2..90d0f056 100644 --- a/util/src/entities/Application.ts +++ b/util/src/entities/Application.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { Guild } from "./Guild"; import { Team } from "./Team"; @@ -38,14 +38,14 @@ export class Application extends BaseClass { @Column() verify_key: string; - @Column() + @RelationId((application: Application) => application.team) team_id: string; @JoinColumn({ name: "team_id" }) @ManyToOne(() => Team, (team: Team) => team.id) team?: Team; - @Column() + @RelationId((application: Application) => application.guild) guild_id: string; @JoinColumn({ name: "guild_id" }) diff --git a/util/src/entities/AuditLog.ts b/util/src/entities/AuditLog.ts index 53e99261..2195771b 100644 --- a/util/src/entities/AuditLog.ts +++ b/util/src/entities/AuditLog.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { ChannelPermissionOverwrite } from "./Channel"; import { User } from "./User"; @@ -43,14 +43,14 @@ export enum AuditLogEvents { @Entity("audit_logs") export class AuditLogEntry extends BaseClass { - @Column() + @RelationId((auditlog: AuditLogEntry) => auditlog.target) target_id: string; @JoinColumn({ name: "user_id" }) @ManyToOne(() => User, (user: User) => user.id) target?: User; - @Column() + @RelationId((auditlog: AuditLogEntry) => auditlog.user) user_id: string; @JoinColumn({ name: "user_id" }) diff --git a/util/src/entities/Ban.ts b/util/src/entities/Ban.ts index ceea4a05..2553e886 100644 --- a/util/src/entities/Ban.ts +++ b/util/src/entities/Ban.ts @@ -1,25 +1,25 @@ -import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { Guild } from "./Guild"; import { User } from "./User"; @Entity("bans") export class Ban extends BaseClass { - @Column() + @RelationId((ban: Ban) => ban.user) user_id: string; @JoinColumn({ name: "user_id" }) @ManyToOne(() => User, (user: User) => user.id) user: User; - @Column() + @RelationId((ban: Ban) => ban.guild) guild_id: string; @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, (guild: Guild) => guild.id) guild: Guild; - @Column() + @RelationId((ban: Ban) => ban.executor) executor_id: string; @JoinColumn({ name: "executor_id" }) diff --git a/util/src/entities/Channel.ts b/util/src/entities/Channel.ts index 5845607a..d26f1054 100644 --- a/util/src/entities/Channel.ts +++ b/util/src/entities/Channel.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToMany, ManyToOne } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToMany, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { Guild } from "./Guild"; import { Message } from "./Message"; @@ -25,35 +25,35 @@ export class Channel extends BaseClass { @Column({ type: "simple-enum", enum: ChannelType }) type: ChannelType; - @Column("simple-array") + @RelationId((channel: Channel) => channel.recipients) recipient_ids: string[]; @JoinColumn({ name: "recipient_ids" }) @ManyToMany(() => User, (user: User) => user.id) recipients?: User[]; - @Column() + @RelationId((channel: Channel) => channel.last_message) last_message_id: string; @JoinColumn({ name: "last_message_id" }) @ManyToOne(() => Message, (message: Message) => message.id) last_message?: Message; - @Column() + @RelationId((channel: Channel) => channel.guild) guild_id?: string; @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, (guild: Guild) => guild.id) guild: Guild; - @Column() + @RelationId((channel: Channel) => channel.parent) parent_id: string; @JoinColumn({ name: "parent_id" }) @ManyToOne(() => Channel, (channel: Channel) => channel.id) parent?: Channel; - @Column() + @RelationId((channel: Channel) => channel.owner) owner_id: string; @JoinColumn({ name: "owner_id" }) diff --git a/util/src/entities/Config.ts b/util/src/entities/Config.ts new file mode 100644 index 00000000..60d84958 --- /dev/null +++ b/util/src/entities/Config.ts @@ -0,0 +1,274 @@ +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { Snowflake } from "../util"; +import { BaseClass } from "./BaseClass"; +import crypto from "crypto"; + +@Entity("config") +export class ConfigEntity extends BaseClass { + @Column("simple-json") + value: ConfigValue; +} + +export interface RateLimitOptions { + bot?: number; + count: number; + window: number; + onyIp?: boolean; +} + +export interface Region { + id: string; + name: string; + vip: boolean; + custom: boolean; + deprecated: boolean; + optimal: boolean; +} + +export interface KafkaBroker { + ip: string; + port: number; +} + +export interface ConfigValue { + gateway: { + endpointClient: string | null; + endpoint: string | null; + }; + cdn: { + endpointClient: string | null; + endpoint: string | null; + }; + general: { + instance_id: string; + }; + permissions: { + user: { + createGuilds: boolean; + }; + }; + limits: { + user: { + maxGuilds: number; + maxUsername: number; + maxFriends: number; + }; + guild: { + maxRoles: number; + maxMembers: number; + maxChannels: number; + maxChannelsInCategory: number; + hideOfflineMember: number; + }; + message: { + maxCharacters: number; + maxTTSCharacters: number; + maxReactions: number; + maxAttachmentSize: number; + maxBulkDelete: number; + }; + channel: { + maxPins: number; + maxTopic: number; + }; + rate: { + ip: Omit; + global: RateLimitOptions; + error: RateLimitOptions; + routes: { + guild: RateLimitOptions; + webhook: RateLimitOptions; + channel: RateLimitOptions; + auth: { + login: RateLimitOptions; + register: RateLimitOptions; + }; + // TODO: rate limit configuration for all routes + }; + }; + }; + security: { + autoUpdate: boolean | number; + requestSignature: string; + jwtSecret: string; + forwadedFor: string | null; // header to get the real user ip address + captcha: { + enabled: boolean; + service: "recaptcha" | "hcaptcha" | null; // TODO: hcaptcha, custom + sitekey: string | null; + secret: string | null; + }; + ipdataApiKey: string | null; + }; + login: { + requireCaptcha: boolean; + }; + register: { + email: { + necessary: boolean; // we have to use necessary instead of required as the cli tool uses json schema and can't use required + allowlist: boolean; + blocklist: boolean; + domains: string[]; + }; + dateOfBirth: { + necessary: boolean; + minimum: number; // in years + }; + requireCaptcha: boolean; + requireInvite: boolean; + allowNewRegistration: boolean; + allowMultipleAccounts: boolean; + blockProxies: boolean; + password: { + minLength: number; + minNumbers: number; + minUpperCase: number; + minSymbols: number; + }; + }; + regions: { + default: string; + available: Region[]; + }; + rabbitmq: { + host: string | null; + }; + kafka: { + brokers: KafkaBroker[] | null; + }; +} + +export const DefaultConfigOptions: ConfigValue = { + gateway: { + endpointClient: null, + endpoint: null, + }, + cdn: { + endpointClient: null, + endpoint: null, + }, + general: { + instance_id: Snowflake.generate(), + }, + permissions: { + user: { + createGuilds: true, + }, + }, + limits: { + user: { + maxGuilds: 100, + maxUsername: 32, + maxFriends: 1000, + }, + guild: { + maxRoles: 250, + maxMembers: 250000, + maxChannels: 500, + maxChannelsInCategory: 50, + hideOfflineMember: 1000, + }, + message: { + maxCharacters: 2000, + maxTTSCharacters: 200, + maxReactions: 20, + maxAttachmentSize: 8388608, + maxBulkDelete: 100, + }, + channel: { + maxPins: 50, + maxTopic: 1024, + }, + rate: { + ip: { + count: 500, + window: 5, + }, + global: { + count: 20, + window: 5, + bot: 250, + }, + error: { + count: 10, + window: 5, + }, + routes: { + guild: { + count: 5, + window: 5, + }, + webhook: { + count: 5, + window: 20, + }, + channel: { + count: 5, + window: 20, + }, + auth: { + login: { + count: 5, + window: 60, + }, + register: { + count: 2, + window: 60 * 60 * 12, + }, + }, + }, + }, + }, + security: { + autoUpdate: true, + requestSignature: crypto.randomBytes(32).toString("base64"), + jwtSecret: crypto.randomBytes(256).toString("base64"), + forwadedFor: null, + // forwadedFor: "X-Forwarded-For" // nginx/reverse proxy + // forwadedFor: "CF-Connecting-IP" // cloudflare: + captcha: { + enabled: false, + service: null, + sitekey: null, + secret: null, + }, + ipdataApiKey: "eca677b284b3bac29eb72f5e496aa9047f26543605efe99ff2ce35c9", + }, + login: { + requireCaptcha: false, + }, + register: { + email: { + necessary: true, + allowlist: false, + blocklist: true, + domains: [], // TODO: efficiently save domain blocklist in database + // domains: fs.readFileSync(__dirname + "/blockedEmailDomains.txt", { encoding: "utf8" }).split("\n"), + }, + dateOfBirth: { + necessary: true, + minimum: 13, + }, + requireInvite: false, + requireCaptcha: true, + allowNewRegistration: true, + allowMultipleAccounts: true, + blockProxies: true, + password: { + minLength: 8, + minNumbers: 2, + minUpperCase: 2, + minSymbols: 0, + }, + }, + regions: { + default: "fosscord", + available: [{ id: "fosscord", name: "Fosscord", vip: false, custom: false, deprecated: false, optimal: false }], + }, + rabbitmq: { + host: null, + }, + kafka: { + brokers: null, + }, +}; diff --git a/util/src/entities/Emoji.ts b/util/src/entities/Emoji.ts index 366549db..b31ddb3b 100644 --- a/util/src/entities/Emoji.ts +++ b/util/src/entities/Emoji.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToMany, ManyToOne } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToMany, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { Guild } from "./Guild"; import { Role } from "./Role"; @@ -30,7 +30,7 @@ export class Emoji extends BaseClass { @Column() url: string; - @Column("simple-array") + @RelationId((emoji: Emoji) => emoji.roles) role_ids: string[]; @JoinColumn({ name: "role_ids" }) diff --git a/util/src/entities/Guild.ts b/util/src/entities/Guild.ts index d46d31bc..d7b4dff4 100644 --- a/util/src/entities/Guild.ts +++ b/util/src/entities/Guild.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToMany, ManyToOne, OneToOne } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToMany, ManyToOne, OneToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { Channel } from "./Channel"; import { Emoji } from "./Emoji"; @@ -10,7 +10,7 @@ import { VoiceState } from "./VoiceState"; @Entity("guilds") export class Guild extends BaseClass { - @Column() + @RelationId((guild: Guild) => guild.afk_channel) afk_channel_id?: string; @JoinColumn({ name: "afk_channel_id" }) @@ -64,35 +64,35 @@ export class Guild extends BaseClass { @Column() presence_count?: number; // users online - @Column("simple-array") + @RelationId((guild: Guild) => guild.members) member_ids: string[]; @JoinColumn({ name: "member_ids" }) @ManyToMany(() => Member, (member: Member) => member.id) members: Member[]; - @Column("simple-array") + @RelationId((guild: Guild) => guild.roles) role_ids: string[]; @JoinColumn({ name: "role_ids" }) @ManyToMany(() => Role, (role: Role) => role.id) roles: Role[]; - @Column("simple-array") + @RelationId((guild: Guild) => guild.channels) channel_ids: string[]; @JoinColumn({ name: "channel_ids" }) @ManyToMany(() => Channel, (channel: Channel) => channel.id) channels: Channel[]; - @Column("simple-array") + @RelationId((guild: Guild) => guild.emojis) emoji_ids: string[]; @JoinColumn({ name: "emoji_ids" }) @ManyToMany(() => Emoji, (emoji: Emoji) => emoji.id) emojis: Emoji[]; - @Column("simple-array") + @RelationId((guild: Guild) => guild.voice_states) voice_state_ids: string[]; @JoinColumn({ name: "voice_state_ids" }) @@ -105,7 +105,7 @@ export class Guild extends BaseClass { @Column() name: string; - @Column() + @RelationId((guild: Guild) => guild.owner) owner_id: string; @JoinColumn({ name: "owner_id" }) @@ -121,11 +121,14 @@ export class Guild extends BaseClass { @Column() premium_tier?: number; // nitro boost level + @RelationId((guild: Guild) => guild.public_updates_channel) + public_updates_channel_id: string; + @JoinColumn({ name: "public_updates_channel_id" }) @ManyToOne(() => Channel, (channel: Channel) => channel.id) public_updates_channel?: Channel; - @Column() + @RelationId((guild: Guild) => guild.rules_channel) rules_channel_id?: string; @JoinColumn({ name: "rules_channel_id" }) @@ -138,7 +141,7 @@ export class Guild extends BaseClass { @Column() splash?: string; - @Column() + @RelationId((guild: Guild) => guild.system_channel) system_channel_id?: string; @JoinColumn({ name: "system_channel_id" }) @@ -151,6 +154,9 @@ export class Guild extends BaseClass { @Column() unavailable?: boolean; + @RelationId((guild: Guild) => guild.vanity_url) + vanity_url_code?: string; + @JoinColumn({ name: "vanity_url_code" }) @OneToOne(() => Invite, (invite: Invite) => invite.code) vanity_url?: Invite; @@ -170,6 +176,9 @@ export class Guild extends BaseClass { }[]; }; + @RelationId((guild: Guild) => guild.widget_channel) + widget_channel_id?: string; + @JoinColumn({ name: "widget_channel_id" }) @ManyToOne(() => Channel, (channel: Channel) => channel.id) widget_channel?: Channel; diff --git a/util/src/entities/Invite.ts b/util/src/entities/Invite.ts index 19f7206a..eac0cba0 100644 --- a/util/src/entities/Invite.ts +++ b/util/src/entities/Invite.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { Channel } from "./Channel"; import { Guild } from "./Guild"; @@ -27,29 +27,29 @@ export class Invite extends BaseClass { @Column() expires_at: Date; - @Column() + @RelationId((invite: Invite) => invite.guild) guild_id: string; @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, (guild: Guild) => guild.id) guild: Guild; - @Column() + @RelationId((invite: Invite) => invite.channel) channel_id: string; @JoinColumn({ name: "channel_id" }) @ManyToOne(() => Channel, (channel: Channel) => channel.id) channel: Channel; - @Column() + @RelationId((invite: Invite) => invite.inviter) inviter_id: string; @JoinColumn({ name: "inviter_id" }) @ManyToOne(() => User, (user: User) => user.id) inviter: User; - @Column() - target_usser_id: string; + @RelationId((invite: Invite) => invite.target_user) + target_user_id: string; @JoinColumn({ name: "target_user_id" }) @ManyToOne(() => User, (user: User) => user.id) diff --git a/util/src/entities/Member.ts b/util/src/entities/Member.ts index c367755e..01634d9e 100644 --- a/util/src/entities/Member.ts +++ b/util/src/entities/Member.ts @@ -1,18 +1,18 @@ import { PublicUser, User } from "./User"; import { BaseClass } from "./BaseClass"; -import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; import { Guild } from "./Guild"; @Entity("members") export class Member extends BaseClass { - @Column() + @RelationId((member: Member) => member.user) user_id: string; @JoinColumn({ name: "user_id" }) @ManyToOne(() => User, (user: User) => user.id) user: User; - @Column() + @RelationId((member: Member) => member.guild) guild_id: string; @JoinColumn({ name: "guild_id" }) diff --git a/util/src/entities/Message.ts b/util/src/entities/Message.ts index 2c0918c7..9daf042c 100644 --- a/util/src/entities/Message.ts +++ b/util/src/entities/Message.ts @@ -4,7 +4,16 @@ import { Role } from "./Role"; import { Channel } from "./Channel"; import { InteractionType } from "../interfaces/Interaction"; import { Application } from "./Application"; -import { Column, CreateDateColumn, Entity, JoinColumn, ManyToMany, ManyToOne, UpdateDateColumn } from "typeorm"; +import { + Column, + CreateDateColumn, + Entity, + JoinColumn, + ManyToMany, + ManyToOne, + RelationId, + UpdateDateColumn, +} from "typeorm"; import { BaseClass } from "./BaseClass"; import { Guild } from "./Guild"; import { Webhook } from "./Webhook"; @@ -34,42 +43,42 @@ export class Message extends BaseClass { @Column() id: string; - @Column() + @RelationId((message: Message) => message.channel) channel_id: string; @JoinColumn({ name: "channel_id" }) @ManyToOne(() => Channel, (channel: Channel) => channel.id) channel: Channel; - @Column() + @RelationId((message: Message) => message.guild) guild_id: string; @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, (guild: Guild) => guild.id) guild?: Guild; - @Column() + @RelationId((message: Message) => message.author) author_id: string; @JoinColumn({ name: "author_id" }) @ManyToOne(() => User, (user: User) => user.id) author?: User; - @Column() + @RelationId((message: Message) => message.member) member_id: string; @JoinColumn({ name: "member_id" }) @ManyToOne(() => Member, (member: Member) => member.id) member?: Member; - @Column() + @RelationId((message: Message) => message.webhook) webhook_id: string; @JoinColumn({ name: "webhook_id" }) @ManyToOne(() => Webhook, (webhook: Webhook) => webhook.id) webhook?: Webhook; - @Column() + @RelationId((message: Message) => message.application) application_id: string; @JoinColumn({ name: "application_id" }) @@ -93,21 +102,21 @@ export class Message extends BaseClass { @Column() mention_everyone?: boolean; - @Column("simple-array") + @RelationId((message: Message) => message.mention_users) mention_user_ids: string[]; @JoinColumn({ name: "mention_user_ids" }) @ManyToMany(() => User, (user: User) => user.id) mention_users: User[]; - @Column("simple-array") + @RelationId((message: Message) => message.mention_roles) mention_role_ids: string[]; @JoinColumn({ name: "mention_role_ids" }) @ManyToMany(() => Role, (role: Role) => role.id) mention_roles: Role[]; - @Column("simple-array") + @RelationId((message: Message) => message.mention_channels) mention_channel_ids: string[]; @JoinColumn({ name: "mention_channel_ids" }) diff --git a/util/src/entities/RateLimit.ts b/util/src/entities/RateLimit.ts index 374a0759..3ac35df3 100644 --- a/util/src/entities/RateLimit.ts +++ b/util/src/entities/RateLimit.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { User } from "./User"; @@ -7,7 +7,7 @@ export class RateLimit extends BaseClass { @Column() id: "global" | "error" | string; // channel_239842397 | guild_238927349823 | webhook_238923423498 - @Column() + @RelationId((rate_limit: RateLimit) => rate_limit.user) user_id: string; @JoinColumn({ name: "user_id" }) diff --git a/util/src/entities/ReadState.ts b/util/src/entities/ReadState.ts index 7c56b6c6..0310cb5f 100644 --- a/util/src/entities/ReadState.ts +++ b/util/src/entities/ReadState.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { Channel } from "./Channel"; import { Message } from "./Message"; @@ -6,20 +6,23 @@ import { User } from "./User"; @Entity("read_states") export class ReadState extends BaseClass { - @Column() + @RelationId((read_state: ReadState) => read_state.channel) channel_id: string; @JoinColumn({ name: "channel_id" }) @ManyToOne(() => Channel, (channel: Channel) => channel.id) channel: Channel; - @Column() + @RelationId((read_state: ReadState) => read_state.user) user_id: string; @JoinColumn({ name: "user_id" }) @ManyToOne(() => User, (user: User) => user.id) user: User; + @RelationId((read_state: ReadState) => read_state.last_message) + last_message_id: string; + @JoinColumn({ name: "last_message_id" }) @ManyToOne(() => Message, (message: Message) => message.id) last_message?: Message; diff --git a/util/src/entities/Relationship.ts b/util/src/entities/Relationship.ts index bd5861f0..3e1280c7 100644 --- a/util/src/entities/Relationship.ts +++ b/util/src/entities/Relationship.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { User } from "./User"; @@ -11,7 +11,7 @@ export enum RelationshipType { @Entity("relationships") export class Relationship extends BaseClass { - @Column() + @RelationId((relationship: Relationship) => relationship.user) user_id: string; @JoinColumn({ name: "user_id" }) diff --git a/util/src/entities/Role.ts b/util/src/entities/Role.ts index 7bb144cc..e48fd293 100644 --- a/util/src/entities/Role.ts +++ b/util/src/entities/Role.ts @@ -1,10 +1,10 @@ -import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { Guild } from "./Guild"; @Entity("roles") export class Role extends BaseClass { - @Column() + @RelationId((role: Role) => role.guild) guild_id: string; @JoinColumn({ name: "guild_id" }) diff --git a/util/src/entities/Team.ts b/util/src/entities/Team.ts index 5e645650..fa1b0ed2 100644 --- a/util/src/entities/Team.ts +++ b/util/src/entities/Team.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToMany, ManyToOne } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToMany, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { TeamMember } from "./TeamMember"; import { User } from "./User"; @@ -8,7 +8,7 @@ export class Team extends BaseClass { @Column() icon?: string; - @Column("simple-array") + @RelationId((team: Team) => team.members) member_ids: string[]; @JoinColumn({ name: "member_ids" }) @@ -18,7 +18,7 @@ export class Team extends BaseClass { @Column() name: string; - @Column() + @RelationId((team: Team) => team.owner_user) owner_user_id: string; @JoinColumn({ name: "owner_user_id" }) diff --git a/util/src/entities/TeamMember.ts b/util/src/entities/TeamMember.ts index 2b1c76f1..f0b54c6f 100644 --- a/util/src/entities/TeamMember.ts +++ b/util/src/entities/TeamMember.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { User } from "./User"; @@ -15,14 +15,14 @@ export class TeamMember extends BaseClass { @Column("simple-array") permissions: string[]; - @Column() + @RelationId((member: TeamMember) => member.team) team_id: string; @JoinColumn({ name: "team_id" }) @ManyToOne(() => require("./Team").Team, (team: import("./Team").Team) => team.id) team: import("./Team").Team; - @Column() + @RelationId((member: TeamMember) => member.user) user_id: string; @JoinColumn({ name: "user_id" }) diff --git a/util/src/entities/Template.ts b/util/src/entities/Template.ts index 5c9a5120..c8d2034c 100644 --- a/util/src/entities/Template.ts +++ b/util/src/entities/Template.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { Guild } from "./Guild"; import { User } from "./User"; @@ -17,6 +17,9 @@ export class Template extends BaseClass { @Column() usage_count?: number; + @RelationId((template: Template) => template.creator) + creator_id: string; + @JoinColumn({ name: "creator_id" }) @ManyToOne(() => User, (user: User) => user.id) creator: User; @@ -27,6 +30,9 @@ export class Template extends BaseClass { @Column() updated_at: Date; + @RelationId((template: Template) => template.source_guild) + source_guild_id: string; + @JoinColumn({ name: "source_guild_id" }) @ManyToOne(() => Guild, (guild: Guild) => guild.id) source_guild: Guild; diff --git a/util/src/entities/User.ts b/util/src/entities/User.ts index 39e59da4..bdf0d35f 100644 --- a/util/src/entities/User.ts +++ b/util/src/entities/User.ts @@ -1,8 +1,10 @@ -import { Column, Entity, JoinColumn, OneToMany } from "typeorm"; +import { Column, Entity, JoinColumn, OneToMany, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { BitField } from "../util/BitField"; import { Relationship } from "./Relationship"; import { ConnectedAccount } from "./ConnectedAccount"; +import { HTTPError } from "lambert-server"; +import { Guild } from "./Guild"; export const PublicUserProjection = { username: true, @@ -24,6 +26,13 @@ export class User extends BaseClass { @Column() discriminator: string; // #0001 4 digit long string from #0001 - #9999 + setDiscriminator(val: string) { + const number = Number(val); + if (isNaN(number)) throw new Error("invalid discriminator"); + if (number > 0 && number < 10000) throw new Error("discriminator must be between 1 and 9999"); + this.discriminator = val; + } + @Column() avatar?: string; // hash of the user avatar @@ -84,17 +93,21 @@ export class User extends BaseClass { @Column({ type: "bigint" }) public_flags: bigint; - @Column("simple-array") // string in simple-array must not contain commas - guilds: string[]; // array of guild ids the user is part of + @RelationId((user: User) => user.guilds) + guild_ids: string[]; // array of guild ids the user is part of - @Column("simple-array") // string in simple-array must not contain commas + @JoinColumn({ name: "guild_ids" }) + @OneToMany(() => Guild, (guild: Guild) => guild.id) + guilds: Guild[]; + + @RelationId((user: User) => user.relationships) relationship_ids: string[]; // array of guild ids the user is part of @JoinColumn({ name: "relationship_ids" }) @OneToMany(() => User, (user: User) => user.id) relationships: Relationship[]; - @Column("simple-array") // string in simple-array must not contain commas + @RelationId((user: User) => user.connected_accounts) connected_account_ids: string[]; // array of guild ids the user is part of @JoinColumn({ name: "connected_account_ids" }) @@ -102,14 +115,28 @@ export class User extends BaseClass { connected_accounts: ConnectedAccount[]; @Column({ type: "simple-json", select: false }) - user_data: { + data: { valid_tokens_since: Date; // all tokens with a previous issue date are invalid hash: string; // hash of the password, salt is saved in password (bcrypt) - fingerprints: string[]; // array of fingerprints -> used to prevent multiple accounts }; + @Column({ type: "simple-array" }) + fingerprints: string[]; // array of fingerprints -> used to prevent multiple accounts + @Column("simple-json") settings: UserSettings; + + static async getPublicUser(user_id: string, additional_fields?: any) { + const user = await User.findOne( + { id: user_id }, + { + ...PublicUserProjection, + ...additional_fields, + } + ); + if (!user) throw new HTTPError("User not found", 404); + return user; + } } export interface UserSettings { diff --git a/util/src/entities/VoiceState.ts b/util/src/entities/VoiceState.ts index 2416c6c0..6707a575 100644 --- a/util/src/entities/VoiceState.ts +++ b/util/src/entities/VoiceState.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, OneToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { Channel } from "./Channel"; import { Guild } from "./Guild"; @@ -6,14 +6,23 @@ import { User } from "./User"; @Entity("voice_states") export class VoiceState extends BaseClass { + @RelationId((voice_state: VoiceState) => voice_state.guild) + guild_id: string; + @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, (guild: Guild) => guild.id) guild?: Guild; + @RelationId((voice_state: VoiceState) => voice_state.channel) + channel_id: string; + @JoinColumn({ name: "channel_id" }) @ManyToOne(() => Channel, (channel: Channel) => channel.id) channel: Channel; + @RelationId((voice_state: VoiceState) => voice_state.user) + user_id: string; + @JoinColumn({ name: "user_id" }) @ManyToOne(() => User, (user: User) => user.id) user: User; diff --git a/util/src/entities/Webhook.ts b/util/src/entities/Webhook.ts index 54233638..dc929c18 100644 --- a/util/src/entities/Webhook.ts +++ b/util/src/entities/Webhook.ts @@ -1,5 +1,9 @@ -import { Column, Entity, JoinColumn } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; +import { Application } from "./Application"; import { BaseClass } from "./BaseClass"; +import { Channel } from "./Channel"; +import { Guild } from "./Guild"; +import { User } from "./User"; export enum WebhookType { Incoming = 1, @@ -23,18 +27,38 @@ export class Webhook extends BaseClass { @Column() token?: string; - @JoinColumn() - guild?: string; + @RelationId((webhook: Webhook) => webhook.guild) + guild_id: string; - @JoinColumn() - channel: string; + @JoinColumn({ name: "guild_id" }) + @ManyToOne(() => Guild, (guild: Guild) => guild.id) + guild: Guild; - @JoinColumn() - application?: string; + @RelationId((webhook: Webhook) => webhook.channel) + channel_id: string; - @JoinColumn() - user?: string; + @JoinColumn({ name: "channel_id" }) + @ManyToOne(() => Channel, (channel: Channel) => channel.id) + channel: Channel; - @JoinColumn() - source_guild: string; + @RelationId((webhook: Webhook) => webhook.application) + application_id: string; + + @JoinColumn({ name: "application_id" }) + @ManyToOne(() => Application, (application: Application) => application.id) + application: Application; + + @RelationId((webhook: Webhook) => webhook.user) + user_id: string; + + @JoinColumn({ name: "user_id" }) + @ManyToOne(() => User, (user: User) => user.id) + user: User; + + @RelationId((webhook: Webhook) => webhook.guild) + source_guild_id: string; + + @JoinColumn({ name: "source_guild_id" }) + @ManyToOne(() => Guild, (guild: Guild) => guild.id) + source_guild: Guild; } diff --git a/util/src/entities/index.ts b/util/src/entities/index.ts index 9cb10016..b9e361c1 100644 --- a/util/src/entities/index.ts +++ b/util/src/entities/index.ts @@ -3,6 +3,7 @@ export * from "./AuditLog"; export * from "./Ban"; export * from "./BaseClass"; export * from "./Channel"; +export * from "./Config"; export * from "./ConnectedAccount"; export * from "./Emoji"; export * from "./Guild";