From 7a981de88331de83152fe0224f9332fffe8a43bb Mon Sep 17 00:00:00 2001 From: Johann150 Date: Wed, 24 Aug 2022 23:57:34 +0200 Subject: [PATCH] refactor: remove note.mentionedRemoteUsers column The column mentionedRemoteUsers on the note table in the database is firstly in the wrong type since it contains JSON data but is typed as text. Secondly it seems redundant, since that data can be acquired by using the note.mentions column to fetch the respective data instead. Co-authored-by: Francis Dinh --- ...00-remove-mentioned-remote-users-column.js | 12 ++++++++++ packages/backend/src/models/entities/note.ts | 12 ---------- .../src/remote/activitypub/renderer/note.ts | 23 +++++++++++-------- .../backend/src/services/messages/create.ts | 5 ---- packages/backend/src/services/note/create.ts | 12 +--------- packages/backend/src/services/note/delete.ts | 15 ++++++------ 6 files changed, 34 insertions(+), 45 deletions(-) create mode 100644 packages/backend/migration/1661376843000-remove-mentioned-remote-users-column.js diff --git a/packages/backend/migration/1661376843000-remove-mentioned-remote-users-column.js b/packages/backend/migration/1661376843000-remove-mentioned-remote-users-column.js new file mode 100644 index 000000000..42d79b5b5 --- /dev/null +++ b/packages/backend/migration/1661376843000-remove-mentioned-remote-users-column.js @@ -0,0 +1,12 @@ +export class removeMentionedRemoteUsersColumn1661376843000 { + name = 'removeMentionedRemoteUsersColumn1661376843000'; + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "mentionedRemoteUsers"`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" ADD "mentionedRemoteUsers" TEXT NOT NULL DEFAULT '[]'::text`); + await queryRunner.query(`UPDATE "note" SET "mentionedRemoteUsers" = (SELECT COALESCE(json_agg(row_to_json("data"))::text, '[]') FROM (SELECT "url", "uri", "username", "host" FROM "user" JOIN "user_profile" ON "user"."id" = "user_profile". "userId" WHERE "user"."host" IS NOT NULL AND "user"."id" = ANY("note"."mentions")) AS "data")`); + } +} diff --git a/packages/backend/src/models/entities/note.ts b/packages/backend/src/models/entities/note.ts index ee7cbec43..d1e6b9f93 100644 --- a/packages/backend/src/models/entities/note.ts +++ b/packages/backend/src/models/entities/note.ts @@ -155,11 +155,6 @@ export class Note { }) public mentions: User['id'][]; - @Column('text', { - default: '[]', - }) - public mentionedRemoteUsers: string; - @Column('varchar', { length: 128, array: true, default: '{}', }) @@ -233,10 +228,3 @@ export class Note { } } } - -export type IMentionedRemoteUsers = { - uri: string; - url?: string; - username: string; - host: string; -}[]; diff --git a/packages/backend/src/remote/activitypub/renderer/note.ts b/packages/backend/src/remote/activitypub/renderer/note.ts index e662c0e92..1bcb5eae2 100644 --- a/packages/backend/src/remote/activitypub/renderer/note.ts +++ b/packages/backend/src/remote/activitypub/renderer/note.ts @@ -1,6 +1,6 @@ import { In, IsNull } from 'typeorm'; import config from '@/config/index.js'; -import { Note, IMentionedRemoteUsers } from '@/models/entities/note.js'; +import { Note } from '@/models/entities/note.js'; import { DriveFile } from '@/models/entities/drive-file.js'; import { DriveFiles, Notes, Users, Emojis, Polls } from '@/models/index.js'; import { Emoji } from '@/models/entities/emoji.js'; @@ -55,28 +55,31 @@ export default async function renderNote(note: Note, dive = true, isTalk = false const attributedTo = `${config.url}/users/${note.userId}`; - const mentions = (JSON.parse(note.mentionedRemoteUsers) as IMentionedRemoteUsers).map(x => x.uri); + const mentionedUsers = note.mentions.length > 0 ? await Users.findBy({ + id: In(note.mentions), + }) : []; + + const mentionUris = mentionedUsers + // only remote users + .filter(user => Users.isRemoteUser(user)) + .map(user => user.uri); let to: string[] = []; let cc: string[] = []; if (note.visibility === 'public') { to = ['https://www.w3.org/ns/activitystreams#Public']; - cc = [`${attributedTo}/followers`].concat(mentions); + cc = [`${attributedTo}/followers`].concat(mentionUris); } else if (note.visibility === 'home') { to = [`${attributedTo}/followers`]; - cc = ['https://www.w3.org/ns/activitystreams#Public'].concat(mentions); + cc = ['https://www.w3.org/ns/activitystreams#Public'].concat(mentionUris); } else if (note.visibility === 'followers') { to = [`${attributedTo}/followers`]; - cc = mentions; + cc = mentionUris; } else { - to = mentions; + to = mentionUris; } - const mentionedUsers = note.mentions.length > 0 ? await Users.findBy({ - id: In(note.mentions), - }) : []; - const hashtagTags = (note.tags || []).map(tag => renderHashtag(tag)); const mentionTags = mentionedUsers.map(u => renderMention(u)); diff --git a/packages/backend/src/services/messages/create.ts b/packages/backend/src/services/messages/create.ts index b5892a891..4a0ea53a8 100644 --- a/packages/backend/src/services/messages/create.ts +++ b/packages/backend/src/services/messages/create.ts @@ -93,11 +93,6 @@ export async function createMessage(user: { id: User['id']; host: User['host']; userId: message.userId, visibility: 'specified', mentions: [ recipientUser.id ], - mentionedRemoteUsers: JSON.stringify([ recipientUser ].map(u => ({ - uri: u.uri, - username: u.username, - host: u.host, - }))), } as Note; const activity = renderActivity(renderCreate(await renderNote(note, false, true), note)); diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 84bfa89eb..9761de0e5 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -15,7 +15,7 @@ import { insertNoteUnread } from '@/services/note/unread.js'; import { extractMentions } from '@/misc/extract-mentions.js'; import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm.js'; import { extractHashtags } from '@/misc/extract-hashtags.js'; -import { Note, IMentionedRemoteUsers } from '@/models/entities/note.js'; +import { Note } from '@/models/entities/note.js'; import { Mutings, Users, NoteWatchings, Notes, Instances, UserProfiles, MutedNotes, Channels, ChannelFollowings, NoteThreadMutings } from '@/models/index.js'; import { DriveFile } from '@/models/entities/drive-file.js'; import { App } from '@/models/entities/app.js'; @@ -537,16 +537,6 @@ async function insertNote(user: { id: User['id']; host: User['host']; }, data: O // Append mentions data if (mentionedUsers.length > 0) { insert.mentions = mentionedUsers.map(u => u.id); - const profiles = await UserProfiles.findBy({ userId: In(insert.mentions) }); - insert.mentionedRemoteUsers = JSON.stringify(mentionedUsers.filter(u => Users.isRemoteUser(u)).map(u => { - const profile = profiles.find(p => p.userId === u.id); - return { - uri: u.uri, - url: profile?.url, - username: u.username, - host: u.host, - } as IMentionedRemoteUsers[0]; - })); } // 投稿を作成 diff --git a/packages/backend/src/services/note/delete.ts b/packages/backend/src/services/note/delete.ts index fc156b584..61b75c963 100644 --- a/packages/backend/src/services/note/delete.ts +++ b/packages/backend/src/services/note/delete.ts @@ -1,4 +1,4 @@ -import { Brackets, In } from 'typeorm'; +import { Brackets, In, IsNull, Not } from 'typeorm'; import { publishNoteStream } from '@/services/stream.js'; import renderDelete from '@/remote/activitypub/renderer/delete.js'; import renderAnnounce from '@/remote/activitypub/renderer/announce.js'; @@ -7,7 +7,7 @@ import { renderActivity } from '@/remote/activitypub/renderer/index.js'; import renderTombstone from '@/remote/activitypub/renderer/tombstone.js'; import config from '@/config/index.js'; import { User, ILocalUser, IRemoteUser } from '@/models/entities/user.js'; -import { Note, IMentionedRemoteUsers } from '@/models/entities/note.js'; +import { Note } from '@/models/entities/note.js'; import { Notes, Users, Instances } from '@/models/index.js'; import { notesChart, perUserNotesChart, instanceChart } from '@/services/chart/index.js'; import { deliverToFollowers, deliverToUser } from '@/remote/activitypub/deliver-manager.js'; @@ -109,11 +109,12 @@ async function getMentionedRemoteUsers(note: Note): Promise { const where = [] as any[]; // mention / reply / dm - const uris = (JSON.parse(note.mentionedRemoteUsers) as IMentionedRemoteUsers).map(x => x.uri); - if (uris.length > 0) { - where.push( - { uri: In(uris) }, - ); + if (note.mentions > 0) { + where.push({ + id: In(note.mentions), + // only remote users, local users are on the server and do not need to be notified + host: Not(IsNull()), + }); } // renote / quote