summary refs log tree commit diff
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2026-04-18 00:23:14 +0200
committerRory& <root@rory.gay>2026-04-18 18:26:34 +0200
commit50aacea1147d712e72e9334f897f6b9f6dffe6d0 (patch)
treecc9b116e43d632d8a317cb742e0bb30512b85227
parentSplit out attachment handling from message handler (diff)
downloadserver-ts-50aacea1147d712e72e9334f897f6b9f6dffe6d0.tar.xz
Fix error logging, dont use simple-array
-rw-r--r--src/api/middlewares/ErrorHandler.ts2
-rw-r--r--src/util/entities/Application.ts6
-rw-r--r--src/util/entities/AutomodRule.ts4
-rw-r--r--src/util/entities/BaseClass.ts2
-rw-r--r--src/util/entities/ConnectedAccount.ts2
-rw-r--r--src/util/entities/Emoji.ts4
-rw-r--r--src/util/entities/Encryption.ts2
-rw-r--r--src/util/entities/Guild.ts6
-rw-r--r--src/util/entities/Member.ts2
-rw-r--r--src/util/entities/TeamMember.ts2
-rw-r--r--src/util/entities/User.ts6
-rw-r--r--src/util/migration/postgres/1776450647000-GuildChannelOrderingAsArray.ts17
-rw-r--r--src/util/migration/postgres/1776450647001-AllSimpleArraysToPgArrays.ts41
13 files changed, 76 insertions, 20 deletions
diff --git a/src/api/middlewares/ErrorHandler.ts b/src/api/middlewares/ErrorHandler.ts

index 02d38def..7b85d5e1 100644 --- a/src/api/middlewares/ErrorHandler.ts +++ b/src/api/middlewares/ErrorHandler.ts
@@ -50,7 +50,7 @@ export function ErrorHandler(error: Error & { type?: string }, req: Request, res code = 50109; message = "The request body contains invalid JSON."; } else { - console.error(`[Error] ${code} ${req.url}\n`, errors, "\nbody:", req.body); + console.error(`[Error] ${code} ${req.url}\n`, errors ?? error, "\nbody:", req.body); if (req.server?.options?.production) { // don't expose internal errors to the user, instead human errors should be thrown as HTTPError diff --git a/src/util/entities/Application.ts b/src/util/entities/Application.ts
index 18a694f9..c4f40343 100644 --- a/src/util/entities/Application.ts +++ b/src/util/entities/Application.ts
@@ -61,7 +61,7 @@ export class Application extends BaseClass { @Column() flags: number = 0; - @Column({ type: "simple-array", nullable: true }) + @Column({ type: "varchar", nullable: true }) redirect_uris: string[] = []; @Column({ nullable: true }) @@ -92,7 +92,7 @@ export class Application extends BaseClass { @OneToOne(() => User, { onDelete: "CASCADE" }) bot?: User; - @Column({ type: "simple-array", nullable: true }) + @Column({ type: "varchar", array: true, nullable: true }) tags?: string[]; @Column({ nullable: true }) @@ -120,7 +120,7 @@ export class Application extends BaseClass { //just for us - //@Column({ type: "simple-array", nullable: true }) + //@Column({ type: "varchar", array: true, nullable: true }) //rpc_origins?: string[]; //@Column({ nullable: true }) diff --git a/src/util/entities/AutomodRule.ts b/src/util/entities/AutomodRule.ts
index f57018ff..97312984 100644 --- a/src/util/entities/AutomodRule.ts +++ b/src/util/entities/AutomodRule.ts
@@ -35,10 +35,10 @@ export class AutomodRule extends BaseClass { @Column() event_type: AutomodRuleEventType; - @Column({ type: "simple-array" }) + @Column({ type: "int8", array: true }) exempt_channels: string[]; - @Column({ type: "simple-array" }) + @Column({ type: "int8", array: true }) exempt_roles: string[]; @Column() diff --git a/src/util/entities/BaseClass.ts b/src/util/entities/BaseClass.ts
index ada9e588..bcebca0f 100644 --- a/src/util/entities/BaseClass.ts +++ b/src/util/entities/BaseClass.ts
@@ -122,5 +122,3 @@ export class BaseClass extends BaseClassWithoutId { if (!this.id) this.id = Snowflake.generate(); } } - -export const ArrayColumn = (opts: ColumnOptions) => (process.env.DATABASE?.startsWith("postgres") ? Column({ ...opts, array: true }) : Column({ ...opts, type: "simple-array" })); diff --git a/src/util/entities/ConnectedAccount.ts b/src/util/entities/ConnectedAccount.ts
index 179f152e..d0ed8097 100644 --- a/src/util/entities/ConnectedAccount.ts +++ b/src/util/entities/ConnectedAccount.ts
@@ -59,7 +59,7 @@ export class ConnectedAccount extends BaseClass { @Column({ select: false }) visibility?: number = 0; - @Column({ type: "simple-array" }) + @Column({ type: "varchar", array: true }) integrations?: string[] = []; @Column({ type: "jsonb", name: "metadata", nullable: true }) diff --git a/src/util/entities/Emoji.ts b/src/util/entities/Emoji.ts
index 4c22921b..586550f9 100644 --- a/src/util/entities/Emoji.ts +++ b/src/util/entities/Emoji.ts
@@ -57,9 +57,9 @@ export class Emoji extends BaseClass { @Column() require_colons: boolean; - @Column({ type: "simple-array" }) + @Column({ type: "int8", array: true }) roles: string[]; // roles this emoji is whitelisted to (new discord feature?) - @Column({ type: "simple-array", nullable: true }) + @Column({ type: "int8", array: true, nullable: true }) groups: string[]; // user groups this emoji is whitelisted to (Spacebar extension) } diff --git a/src/util/entities/Encryption.ts b/src/util/entities/Encryption.ts
index ee92bd38..9c76701a 100644 --- a/src/util/entities/Encryption.ts +++ b/src/util/entities/Encryption.ts
@@ -32,7 +32,7 @@ export class SecuritySettings extends BaseClass { @Column() encryption_permission_mask: number; - @Column({ type: "simple-array" }) + @Column({ type: "varchar", array: true }) allowed_algorithms: string[]; @Column() diff --git a/src/util/entities/Guild.ts b/src/util/entities/Guild.ts
index c38f7238..213c2c96 100644 --- a/src/util/entities/Guild.ts +++ b/src/util/entities/Guild.ts
@@ -101,7 +101,7 @@ export class Guild extends BaseClass { @Column({ nullable: true }) explicit_content_filter?: number; - @Column({ type: "simple-array" }) + @Column({ type: "varchar", array: true }) features: string[] = []; //TODO use enum //TODO: https://discord.com/developers/docs/resources/guild#guild-object-guild-features @@ -267,7 +267,7 @@ export class Guild extends BaseClass { @Column({ type: "jsonb" }) welcome_screen: GuildWelcomeScreen; - @Column({ nullable: true }) + @Column({ nullable: true, type: "int8" }) @RelationId((guild: Guild) => guild.widget_channel) widget_channel_id?: string; @@ -295,7 +295,7 @@ export class Guild extends BaseClass { @Column({ nullable: true }) premium_progress_bar_enabled: boolean = false; - @Column({ select: false, type: "simple-array" }) + @Column({ select: false, type: "int8", array: true }) channel_ordering: string[]; @Column() diff --git a/src/util/entities/Member.ts b/src/util/entities/Member.ts
index 802338ef..8a460afe 100644 --- a/src/util/entities/Member.ts +++ b/src/util/entities/Member.ts
@@ -133,7 +133,7 @@ export class Member extends BaseClassWithoutId { @Column() bio: string; - @Column({ nullable: true, type: "simple-array" }) + @Column({ nullable: true, type: "int4", array: true }) theme_colors?: number[]; // TODO: Separate `User` and `UserProfile` models @Column({ nullable: true }) diff --git a/src/util/entities/TeamMember.ts b/src/util/entities/TeamMember.ts
index 779a8119..72e23b76 100644 --- a/src/util/entities/TeamMember.ts +++ b/src/util/entities/TeamMember.ts
@@ -28,7 +28,7 @@ export class TeamMember extends BaseClass { @Column({ type: "int" }) membership_state: TeamMemberState; - @Column({ type: "simple-array" }) + @Column({ type: "varchar", array: true }) permissions: string[]; @Column() diff --git a/src/util/entities/User.ts b/src/util/entities/User.ts
index e01da3af..e2590f59 100644 --- a/src/util/entities/User.ts +++ b/src/util/entities/User.ts
@@ -61,7 +61,7 @@ export class User extends BaseClass { // TODO: Separate `User` and `UserProfile` models // puyo: changed from [number, number] because it breaks openapi - @Column({ nullable: true, type: "simple-array" }) + @Column({ nullable: true, type: "int4", array: true }) theme_colors?: number[]; @Column({ nullable: true }) @@ -166,7 +166,7 @@ export class User extends BaseClass { hash?: string; // hash of the password, salt is saved in password (bcrypt) }; - @Column({ type: "simple-array", select: false }) + @Column({ type: "varchar", array: true, select: false }) fingerprints: string[] = []; // array of fingerprints -> used to prevent multiple accounts @OneToOne(() => UserSettings, { @@ -180,7 +180,7 @@ export class User extends BaseClass { @OneToMany(() => SecurityKey, (key: SecurityKey) => key.user) security_keys: SecurityKey[]; - @Column({ type: "simple-array", nullable: true }) + @Column({ type: "int8", array: true, nullable: true }) badge_ids?: string[]; @Column({ type: "jsonb", nullable: true }) diff --git a/src/util/migration/postgres/1776450647000-GuildChannelOrderingAsArray.ts b/src/util/migration/postgres/1776450647000-GuildChannelOrderingAsArray.ts new file mode 100644
index 00000000..e75c3e89 --- /dev/null +++ b/src/util/migration/postgres/1776450647000-GuildChannelOrderingAsArray.ts
@@ -0,0 +1,17 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class GuildChannelOrderingAsArray1776450647000 implements MigrationInterface { + name = "GuildChannelOrderingAsArray1776450647000"; + + public async up(queryRunner: QueryRunner): Promise<void> { + // spacebar was randomly adding json data into CSV values, unwrap them + await queryRunner.query(`UPDATE guilds SET channel_ordering = REPLACE(channel_ordering, '"', '') WHERE channel_ordering ~ '"';`); + await queryRunner.query(`UPDATE guilds SET channel_ordering = REPLACE(channel_ordering, '[', '') WHERE channel_ordering ~ '\\[';`); + await queryRunner.query(`UPDATE guilds SET channel_ordering = REPLACE(channel_ordering, ']', '') WHERE channel_ordering ~ '\\]';`); + await queryRunner.query(`ALTER TABLE guilds ALTER COLUMN channel_ordering TYPE int8[] USING string_to_array(channel_ordering, ',')::int8[];`); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + console.log(`Migration ${this.name}.down() not implemented`); + } +} diff --git a/src/util/migration/postgres/1776450647001-AllSimpleArraysToPgArrays.ts b/src/util/migration/postgres/1776450647001-AllSimpleArraysToPgArrays.ts new file mode 100644
index 00000000..44d2c591 --- /dev/null +++ b/src/util/migration/postgres/1776450647001-AllSimpleArraysToPgArrays.ts
@@ -0,0 +1,41 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AllSimpleArraysToPgArrays1776450647001 implements MigrationInterface { + name = "AllSimpleArraysToPgArrays1776450647001"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await this.cleanAndConvertToArray(queryRunner, "applications", "redirect_uris", "varchar"); + await this.cleanAndConvertToArray(queryRunner, "applications", "tags", "varchar"); + // await this.cleanAndConvertToArray(queryRunner, "applications", "rpc_origins", "varchar"); + + await this.cleanAndConvertToArray(queryRunner, "automod_rules", "exempt_channels", "int8"); + await this.cleanAndConvertToArray(queryRunner, "automod_rules", "exempt_roles", "int8"); + + await this.cleanAndConvertToArray(queryRunner, "connected_accounts", "integrations", "varchar"); + + await this.cleanAndConvertToArray(queryRunner, "emojis", "roles", "int8"); + await this.cleanAndConvertToArray(queryRunner, "emojis", "groups", "int8"); + + await this.cleanAndConvertToArray(queryRunner, "guilds", "features", "varchar"); + + await this.cleanAndConvertToArray(queryRunner, "members", "theme_colors", "int4"); + + await this.cleanAndConvertToArray(queryRunner, "team_members", "permissions", "varchar"); + + await this.cleanAndConvertToArray(queryRunner, "users", "theme_colors", "int4"); + await this.cleanAndConvertToArray(queryRunner, "users", "fingerprints", "varchar"); + await this.cleanAndConvertToArray(queryRunner, "users", "badge_ids", "int8"); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + console.log(`Migration ${this.name}.down() not implemented`); + } + + private async cleanAndConvertToArray(queryRunner: QueryRunner, table: string, column: string, type: string) { + // spacebar was randomly adding json data into CSV values, unwrap them + await queryRunner.query(`UPDATE ${table} SET ${column} = REPLACE(${column}, '"', '') WHERE ${column} ~ '"';`); + await queryRunner.query(`UPDATE ${table} SET ${column} = REPLACE(${column}, '[', '') WHERE ${column} ~ '\\[';`); + await queryRunner.query(`UPDATE ${table} SET ${column} = REPLACE(${column}, ']', '') WHERE ${column} ~ '\\]';`); + await queryRunner.query(`ALTER TABLE ${table} ALTER COLUMN ${column} TYPE ${type}[] USING string_to_array(${column}, ',')::${type}[];`); + } +}