From 5f51f7878ea520956896337885789041647c9b25 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Fri, 6 Jun 2025 13:03:25 -0400 Subject: [PATCH 1/2] create IDX_note_url over note.url --- .../1749229288946-create-IDX_note_url.js | 16 ++++++++++++++++ packages/backend/src/models/Note.ts | 1 + 2 files changed, 17 insertions(+) create mode 100644 packages/backend/migration/1749229288946-create-IDX_note_url.js diff --git a/packages/backend/migration/1749229288946-create-IDX_note_url.js b/packages/backend/migration/1749229288946-create-IDX_note_url.js new file mode 100644 index 0000000000..4b2fc25cf7 --- /dev/null +++ b/packages/backend/migration/1749229288946-create-IDX_note_url.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class CreateIDXNoteUrl1749229288946 { + name = 'CreateIDXNoteUrl1749229288946' + + async up(queryRunner) { + await queryRunner.query(`CREATE INDEX IF NOT EXISTS "IDX_note_url" ON "note" ("url") `); + } + + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "public"."IDX_note_url"`); + } +} diff --git a/packages/backend/src/models/Note.ts b/packages/backend/src/models/Note.ts index 90b874f29a..bbe183cfbb 100644 --- a/packages/backend/src/models/Note.ts +++ b/packages/backend/src/models/Note.ts @@ -133,6 +133,7 @@ export class MiNote { }) public uri: string | null; + @Index('IDX_note_url') @Column('varchar', { length: 512, nullable: true, comment: 'The human readable url of a note. it will be null when the note is local.', From 3bf0a737c839f0b7a7ea93e16472f02ebff596ee Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Fri, 6 Jun 2025 13:17:20 -0400 Subject: [PATCH 2/2] match attributionDomains entity to database schema --- .../src/core/activitypub/models/ApPersonService.ts | 12 ++++++++++-- packages/backend/src/models/User.ts | 4 ++-- .../backend/src/server/api/endpoints/i/update.ts | 12 +++++++++--- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/backend/src/core/activitypub/models/ApPersonService.ts b/packages/backend/src/core/activitypub/models/ApPersonService.ts index dde5762f53..631e86c8a8 100644 --- a/packages/backend/src/core/activitypub/models/ApPersonService.ts +++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts @@ -445,7 +445,11 @@ export class ApPersonService implements OnModuleInit, OnApplicationShutdown { makeNotesFollowersOnlyBefore: (person as any).makeNotesFollowersOnlyBefore ?? null, makeNotesHiddenBefore: (person as any).makeNotesHiddenBefore ?? null, emojis, - attributionDomains: (Array.isArray(person.attributionDomains) && person.attributionDomains.every(x => typeof x === 'string')) ? person.attributionDomains : [], + attributionDomains: Array.isArray(person.attributionDomains) + ? person.attributionDomains + .filter((a: unknown) => typeof(a) === 'string' && a.length > 0 && a.length <= 128) + .slice(0, 32) + : [], })) as MiRemoteUser; let _description: string | null = null; @@ -629,7 +633,11 @@ export class ApPersonService implements OnModuleInit, OnApplicationShutdown { // We use "!== false" to handle incorrect types, missing / null values, and "default to true" logic. hideOnlineStatus: person.hideOnlineStatus !== false, isExplorable: person.discoverable !== false, - attributionDomains: (Array.isArray(person.attributionDomains) && person.attributionDomains.every(x => typeof x === 'string')) ? person.attributionDomains : [], + attributionDomains: Array.isArray(person.attributionDomains) + ? person.attributionDomains + .filter((a: unknown) => typeof(a) === 'string' && a.length > 0 && a.length <= 128) + .slice(0, 32) + : [], ...(await this.resolveAvatarAndBanner(exist, person.icon, person.image, person.backgroundUrl).catch(() => ({}))), } as Partial & Pick; diff --git a/packages/backend/src/models/User.ts b/packages/backend/src/models/User.ts index 2f13400944..f40bb41a22 100644 --- a/packages/backend/src/models/User.ts +++ b/packages/backend/src/models/User.ts @@ -390,9 +390,9 @@ export class MiUser { }) public allowUnsignedFetch: UserUnsignedFetchOption; - @Column('varchar', { + @Column('text', { name: 'attributionDomains', - length: 128, array: true, default: '{}', + array: true, default: '{}', }) public attributionDomains: string[]; diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index dad605f151..5a160d632c 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -263,9 +263,15 @@ export const paramDef = { enum: userUnsignedFetchOptions, nullable: false, }, - attributionDomains: { type: 'array', items: { - type: 'string', - } }, + attributionDomains: { + type: 'array', + items: { + type: 'string', + minLength: 1, + maxLength: 128, + }, + maxLength: 32, + }, }, } as const;