From ae5a72a2dfdb31806e7ccccb3d053c60a13b549f Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 10:52:41 +0900 Subject: [PATCH 01/46] =?UTF-8?q?feat:=20=E6=8A=95=E7=A8=BF=E3=81=97?= =?UTF-8?q?=E3=81=9F=E3=82=B3=E3=83=B3=E3=83=86=E3=83=B3=E3=83=84=E3=81=AE?= =?UTF-8?q?AI=E3=81=AB=E3=82=88=E3=82=8B=E5=AD=A6=E7=BF=92=E3=82=92?= =?UTF-8?q?=E8=BB=BD=E6=B8=9B=E3=81=99=E3=82=8B=E3=82=AA=E3=83=97=E3=82=B7?= =?UTF-8?q?=E3=83=A7=E3=83=B3=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve #10819 --- CHANGELOG.md | 11 +++++++++++ locales/ja-JP.yml | 2 ++ .../migration/1683682889948-prevent-ai-larning.js | 11 +++++++++++ .../backend/src/core/entities/UserEntityService.ts | 1 + packages/backend/src/models/entities/UserProfile.ts | 5 +++++ packages/backend/src/models/json-schema/user.ts | 6 +++++- .../src/server/api/endpoints/admin/show-user.ts | 1 + packages/backend/src/server/api/endpoints/i/update.ts | 4 +++- packages/backend/src/server/web/views/clip.pug | 2 ++ packages/backend/src/server/web/views/flash.pug | 2 ++ .../backend/src/server/web/views/gallery-post.pug | 2 ++ packages/backend/src/server/web/views/note.pug | 2 ++ packages/backend/src/server/web/views/page.pug | 2 ++ packages/backend/src/server/web/views/user.pug | 2 ++ packages/backend/test/e2e/users.ts | 4 ++++ packages/frontend/src/pages/settings/privacy.vue | 6 ++++++ 16 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 packages/backend/migration/1683682889948-prevent-ai-larning.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 50e097c683..301fe02ef5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,17 @@ --> +## 13.x.x (unreleased) + +### General +- 投稿したコンテンツのAIによる学習を軽減するオプションを追加 + +### Client +- + +### Server +- + ## 13.12.1 ### Client diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 8bbf9459f5..f9e1e9559f 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1038,6 +1038,8 @@ thisChannelArchived: "このチャンネルはアーカイブされています displayOfNote: "ノートの表示" initialAccountSetting: "初期設定" youFollowing: "フォロー中" +preventAiLarning: "AIによる学習を防止" +preventAiLarningDescription: "投稿したノート、添付した画像などのコンテンツを学習の対象にしないようAIに要求します。これはnoaiフラグをHTMLレスポンスに含めることによって実現されます。" _initialAccountSetting: accountCreated: "アカウントの作成が完了しました!" diff --git a/packages/backend/migration/1683682889948-prevent-ai-larning.js b/packages/backend/migration/1683682889948-prevent-ai-larning.js new file mode 100644 index 0000000000..9d1a19c10b --- /dev/null +++ b/packages/backend/migration/1683682889948-prevent-ai-larning.js @@ -0,0 +1,11 @@ +export class PreventAiLarning1683682889948 { + name = 'PreventAiLarning1683682889948' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ADD "preventAiLarning" boolean NOT NULL DEFAULT true`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "preventAiLarning"`); + } +} diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 453c1473dd..cb0b15fac9 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -445,6 +445,7 @@ export class UserEntityService implements OnModuleInit { carefulBot: profile!.carefulBot, autoAcceptFollowed: profile!.autoAcceptFollowed, noCrawle: profile!.noCrawle, + preventAiLarning: profile!.preventAiLarning, isExplorable: user.isExplorable, isDeleted: user.isDeleted, hideOnlineStatus: user.hideOnlineStatus, diff --git a/packages/backend/src/models/entities/UserProfile.ts b/packages/backend/src/models/entities/UserProfile.ts index 60c1c55de5..6eab846c13 100644 --- a/packages/backend/src/models/entities/UserProfile.ts +++ b/packages/backend/src/models/entities/UserProfile.ts @@ -147,6 +147,11 @@ export class UserProfile { }) public noCrawle: boolean; + @Column('boolean', { + default: true, + }) + public preventAiLarning: boolean; + @Column('boolean', { default: false, }) diff --git a/packages/backend/src/models/json-schema/user.ts b/packages/backend/src/models/json-schema/user.ts index 529c1303d1..9d630db4cd 100644 --- a/packages/backend/src/models/json-schema/user.ts +++ b/packages/backend/src/models/json-schema/user.ts @@ -302,7 +302,11 @@ export const packedMeDetailedOnlySchema = { }, noCrawle: { type: 'boolean', - nullable: true, optional: false, + nullable: false, optional: false, + }, + preventAiLarning: { + type: 'boolean', + nullable: false, optional: false, }, isExplorable: { type: 'boolean', diff --git a/packages/backend/src/server/api/endpoints/admin/show-user.ts b/packages/backend/src/server/api/endpoints/admin/show-user.ts index 42229c8f23..12e656a2f7 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-user.ts @@ -68,6 +68,7 @@ export default class extends Endpoint { emailVerified: profile.emailVerified, autoAcceptFollowed: profile.autoAcceptFollowed, noCrawle: profile.noCrawle, + preventAiLarning: profile.preventAiLarning, alwaysMarkNsfw: profile.alwaysMarkNsfw, autoSensitive: profile.autoSensitive, carefulBot: profile.carefulBot, diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index 6c66300bb7..4cc173c2d0 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -98,7 +98,7 @@ export const meta = { message: 'This feature is restricted by your role.', code: 'RESTRICTED_BY_ROLE', id: '8feff0ba-5ab5-585b-31f4-4df816663fad', - } + }, }, res: { @@ -138,6 +138,7 @@ export const paramDef = { carefulBot: { type: 'boolean' }, autoAcceptFollowed: { type: 'boolean' }, noCrawle: { type: 'boolean' }, + preventAiLarning: { type: 'boolean' }, isBot: { type: 'boolean' }, isCat: { type: 'boolean' }, showTimelineReplies: { type: 'boolean' }, @@ -242,6 +243,7 @@ export default class extends Endpoint { if (typeof ps.carefulBot === 'boolean') profileUpdates.carefulBot = ps.carefulBot; if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed; if (typeof ps.noCrawle === 'boolean') profileUpdates.noCrawle = ps.noCrawle; + if (typeof ps.preventAiLarning === 'boolean') profileUpdates.preventAiLarning = ps.preventAiLarning; if (typeof ps.isCat === 'boolean') updates.isCat = ps.isCat; if (typeof ps.injectFeaturedNote === 'boolean') profileUpdates.injectFeaturedNote = ps.injectFeaturedNote; if (typeof ps.receiveAnnouncementEmail === 'boolean') profileUpdates.receiveAnnouncementEmail = ps.receiveAnnouncementEmail; diff --git a/packages/backend/src/server/web/views/clip.pug b/packages/backend/src/server/web/views/clip.pug index 4c692bf59b..f92a437ca6 100644 --- a/packages/backend/src/server/web/views/clip.pug +++ b/packages/backend/src/server/web/views/clip.pug @@ -21,6 +21,8 @@ block og block meta if profile.noCrawle meta(name='robots' content='noindex') + if profile.preventAiLarning + meta(name='robots' content='noai') meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-id' content=user.id) diff --git a/packages/backend/src/server/web/views/flash.pug b/packages/backend/src/server/web/views/flash.pug index 5166855ea2..fcdb136ed8 100644 --- a/packages/backend/src/server/web/views/flash.pug +++ b/packages/backend/src/server/web/views/flash.pug @@ -21,6 +21,8 @@ block og block meta if profile.noCrawle meta(name='robots' content='noindex') + if profile.preventAiLarning + meta(name='robots' content='noai') meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-id' content=user.id) diff --git a/packages/backend/src/server/web/views/gallery-post.pug b/packages/backend/src/server/web/views/gallery-post.pug index ca0663a481..4470266f82 100644 --- a/packages/backend/src/server/web/views/gallery-post.pug +++ b/packages/backend/src/server/web/views/gallery-post.pug @@ -21,6 +21,8 @@ block og block meta if user.host || profile.noCrawle meta(name='robots' content='noindex') + if profile.preventAiLarning + meta(name='robots' content='noai') meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-id' content=user.id) diff --git a/packages/backend/src/server/web/views/note.pug b/packages/backend/src/server/web/views/note.pug index 65696ea138..84bcd51e2b 100644 --- a/packages/backend/src/server/web/views/note.pug +++ b/packages/backend/src/server/web/views/note.pug @@ -22,6 +22,8 @@ block og block meta if user.host || isRenote || profile.noCrawle meta(name='robots' content='noindex') + if profile.preventAiLarning + meta(name='robots' content='noai') meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-id' content=user.id) diff --git a/packages/backend/src/server/web/views/page.pug b/packages/backend/src/server/web/views/page.pug index 4219e76a52..eef066f57d 100644 --- a/packages/backend/src/server/web/views/page.pug +++ b/packages/backend/src/server/web/views/page.pug @@ -21,6 +21,8 @@ block og block meta if profile.noCrawle meta(name='robots' content='noindex') + if profile.preventAiLarning + meta(name='robots' content='noai') meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-id' content=user.id) diff --git a/packages/backend/src/server/web/views/user.pug b/packages/backend/src/server/web/views/user.pug index 119993fdb5..a25fcf6d7e 100644 --- a/packages/backend/src/server/web/views/user.pug +++ b/packages/backend/src/server/web/views/user.pug @@ -20,6 +20,8 @@ block og block meta if user.host || profile.noCrawle meta(name='robots' content='noindex') + if profile.preventAiLarning + meta(name='robots' content='noai') meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-id' content=user.id) diff --git a/packages/backend/test/e2e/users.ts b/packages/backend/test/e2e/users.ts index 51537dda16..7f556fddf2 100644 --- a/packages/backend/test/e2e/users.ts +++ b/packages/backend/test/e2e/users.ts @@ -145,6 +145,7 @@ describe('ユーザー', () => { carefulBot: user.carefulBot, autoAcceptFollowed: user.autoAcceptFollowed, noCrawle: user.noCrawle, + preventAiLarning: user.preventAiLarning, isExplorable: user.isExplorable, isDeleted: user.isDeleted, hideOnlineStatus: user.hideOnlineStatus, @@ -390,6 +391,7 @@ describe('ユーザー', () => { assert.strictEqual(response.carefulBot, false); assert.strictEqual(response.autoAcceptFollowed, true); assert.strictEqual(response.noCrawle, false); + assert.strictEqual(response.preventAiLarning, true); assert.strictEqual(response.isExplorable, true); assert.strictEqual(response.isDeleted, false); assert.strictEqual(response.hideOnlineStatus, false); @@ -462,6 +464,8 @@ describe('ユーザー', () => { { parameters: (): object => ({ autoAcceptFollowed: false }) }, { parameters: (): object => ({ noCrawle: true }) }, { parameters: (): object => ({ noCrawle: false }) }, + { parameters: (): object => ({ preventAiLarning: false }) }, + { parameters: (): object => ({ preventAiLarning: true }) }, { parameters: (): object => ({ isBot: true }) }, { parameters: (): object => ({ isBot: false }) }, { parameters: (): object => ({ isCat: true }) }, diff --git a/packages/frontend/src/pages/settings/privacy.vue b/packages/frontend/src/pages/settings/privacy.vue index c83c48d5ad..29a9efa2d7 100644 --- a/packages/frontend/src/pages/settings/privacy.vue +++ b/packages/frontend/src/pages/settings/privacy.vue @@ -24,6 +24,10 @@ {{ i18n.ts.noCrawle }} + + {{ i18n.ts.preventAiLarning }}{{ i18n.ts.beta }} + + {{ i18n.ts.makeExplorable }} @@ -71,6 +75,7 @@ import { definePageMetadata } from '@/scripts/page-metadata'; let isLocked = $ref($i.isLocked); let autoAcceptFollowed = $ref($i.autoAcceptFollowed); let noCrawle = $ref($i.noCrawle); +let preventAiLarning = $ref($i.preventAiLarning); let isExplorable = $ref($i.isExplorable); let hideOnlineStatus = $ref($i.hideOnlineStatus); let publicReactions = $ref($i.publicReactions); @@ -86,6 +91,7 @@ function save() { isLocked: !!isLocked, autoAcceptFollowed: !!autoAcceptFollowed, noCrawle: !!noCrawle, + preventAiLarning: !!preventAiLarning, isExplorable: !!isExplorable, hideOnlineStatus: !!hideOnlineStatus, publicReactions: !!publicReactions, From 6a25015a78273f2958a7bde68a749ec4d46466cc Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 10:53:01 +0900 Subject: [PATCH 02/46] =?UTF-8?q?enhance(backend):=20publicReactions?= =?UTF-8?q?=E3=82=92=E3=83=87=E3=83=95=E3=82=A9=E3=83=AB=E3=83=88true?= =?UTF-8?q?=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../1683683083083-public-reactions-default-true.js | 11 +++++++++++ packages/backend/src/models/entities/UserProfile.ts | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 packages/backend/migration/1683683083083-public-reactions-default-true.js diff --git a/packages/backend/migration/1683683083083-public-reactions-default-true.js b/packages/backend/migration/1683683083083-public-reactions-default-true.js new file mode 100644 index 0000000000..195ea02a5e --- /dev/null +++ b/packages/backend/migration/1683683083083-public-reactions-default-true.js @@ -0,0 +1,11 @@ +export class PublicReactionsDefaultTrue1683683083083 { + name = 'PublicReactionsDefaultTrue1683683083083' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "publicReactions" SET DEFAULT true`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "publicReactions" SET DEFAULT false`); + } +} diff --git a/packages/backend/src/models/entities/UserProfile.ts b/packages/backend/src/models/entities/UserProfile.ts index 6eab846c13..2cebc56096 100644 --- a/packages/backend/src/models/entities/UserProfile.ts +++ b/packages/backend/src/models/entities/UserProfile.ts @@ -76,7 +76,7 @@ export class UserProfile { public emailNotificationTypes: string[]; @Column('boolean', { - default: false, + default: true, }) public publicReactions: boolean; From 0c4c4e7202f351881c728bc654c5054699273436 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 10:54:56 +0900 Subject: [PATCH 03/46] =?UTF-8?q?=E5=BF=B5=E3=81=AE=E3=81=9F=E3=82=81noima?= =?UTF-8?q?geai=E3=82=82=E3=81=A4=E3=81=91=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/server/web/views/clip.pug | 1 + packages/backend/src/server/web/views/flash.pug | 1 + packages/backend/src/server/web/views/gallery-post.pug | 1 + packages/backend/src/server/web/views/note.pug | 1 + packages/backend/src/server/web/views/page.pug | 1 + packages/backend/src/server/web/views/user.pug | 1 + 6 files changed, 6 insertions(+) diff --git a/packages/backend/src/server/web/views/clip.pug b/packages/backend/src/server/web/views/clip.pug index f92a437ca6..1491e0f748 100644 --- a/packages/backend/src/server/web/views/clip.pug +++ b/packages/backend/src/server/web/views/clip.pug @@ -22,6 +22,7 @@ block meta if profile.noCrawle meta(name='robots' content='noindex') if profile.preventAiLarning + meta(name='robots' content='noimageai') meta(name='robots' content='noai') meta(name='misskey:user-username' content=user.username) diff --git a/packages/backend/src/server/web/views/flash.pug b/packages/backend/src/server/web/views/flash.pug index fcdb136ed8..5005d27869 100644 --- a/packages/backend/src/server/web/views/flash.pug +++ b/packages/backend/src/server/web/views/flash.pug @@ -22,6 +22,7 @@ block meta if profile.noCrawle meta(name='robots' content='noindex') if profile.preventAiLarning + meta(name='robots' content='noimageai') meta(name='robots' content='noai') meta(name='misskey:user-username' content=user.username) diff --git a/packages/backend/src/server/web/views/gallery-post.pug b/packages/backend/src/server/web/views/gallery-post.pug index 4470266f82..2c1102ee79 100644 --- a/packages/backend/src/server/web/views/gallery-post.pug +++ b/packages/backend/src/server/web/views/gallery-post.pug @@ -22,6 +22,7 @@ block meta if user.host || profile.noCrawle meta(name='robots' content='noindex') if profile.preventAiLarning + meta(name='robots' content='noimageai') meta(name='robots' content='noai') meta(name='misskey:user-username' content=user.username) diff --git a/packages/backend/src/server/web/views/note.pug b/packages/backend/src/server/web/views/note.pug index 84bcd51e2b..d768c4a46d 100644 --- a/packages/backend/src/server/web/views/note.pug +++ b/packages/backend/src/server/web/views/note.pug @@ -23,6 +23,7 @@ block meta if user.host || isRenote || profile.noCrawle meta(name='robots' content='noindex') if profile.preventAiLarning + meta(name='robots' content='noimageai') meta(name='robots' content='noai') meta(name='misskey:user-username' content=user.username) diff --git a/packages/backend/src/server/web/views/page.pug b/packages/backend/src/server/web/views/page.pug index eef066f57d..1dd95c52b8 100644 --- a/packages/backend/src/server/web/views/page.pug +++ b/packages/backend/src/server/web/views/page.pug @@ -22,6 +22,7 @@ block meta if profile.noCrawle meta(name='robots' content='noindex') if profile.preventAiLarning + meta(name='robots' content='noimageai') meta(name='robots' content='noai') meta(name='misskey:user-username' content=user.username) diff --git a/packages/backend/src/server/web/views/user.pug b/packages/backend/src/server/web/views/user.pug index a25fcf6d7e..a5427d2ce0 100644 --- a/packages/backend/src/server/web/views/user.pug +++ b/packages/backend/src/server/web/views/user.pug @@ -21,6 +21,7 @@ block meta if user.host || profile.noCrawle meta(name='robots' content='noindex') if profile.preventAiLarning + meta(name='robots' content='noimageai') meta(name='robots' content='noai') meta(name='misskey:user-username' content=user.username) From 7ae1d6511a68ee8e11f17351a559f7dc1f651938 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 10:57:27 +0900 Subject: [PATCH 04/46] add X-Robots-Tag: noai --- .../src/server/web/ClientServerService.ts | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts index 50b23a0682..12369c927c 100644 --- a/packages/backend/src/server/web/ClientServerService.ts +++ b/packages/backend/src/server/web/ClientServerService.ts @@ -35,8 +35,8 @@ import { RoleService } from '@/core/RoleService.js'; import manifest from './manifest.json' assert { type: 'json' }; import { FeedService } from './FeedService.js'; import { UrlPreviewService } from './UrlPreviewService.js'; -import type { FastifyInstance, FastifyPluginOptions, FastifyReply } from 'fastify'; import { ClientLoggerService } from './ClientLoggerService.js'; +import type { FastifyInstance, FastifyPluginOptions, FastifyReply } from 'fastify'; const _filename = fileURLToPath(import.meta.url); const _dirname = dirname(_filename); @@ -423,6 +423,10 @@ export class ClientServerService { : []; reply.header('Cache-Control', 'public, max-age=15'); + if (profile.preventAiLarning) { + reply.header('X-Robots-Tag', 'noimageai'); + reply.header('X-Robots-Tag', 'noai'); + } return await reply.view('user', { user, profile, me, avatarUrl: user.avatarUrl ?? this.userEntityService.getIdenticonUrl(user), @@ -467,6 +471,10 @@ export class ClientServerService { const profile = await this.userProfilesRepository.findOneByOrFail({ userId: note.userId }); const meta = await this.metaService.fetch(); reply.header('Cache-Control', 'public, max-age=15'); + if (profile.preventAiLarning) { + reply.header('X-Robots-Tag', 'noimageai'); + reply.header('X-Robots-Tag', 'noai'); + } return await reply.view('note', { note: _note, profile, @@ -506,6 +514,10 @@ export class ClientServerService { } else { reply.header('Cache-Control', 'private, max-age=0, must-revalidate'); } + if (profile.preventAiLarning) { + reply.header('X-Robots-Tag', 'noimageai'); + reply.header('X-Robots-Tag', 'noai'); + } return await reply.view('page', { page: _page, profile, @@ -530,6 +542,10 @@ export class ClientServerService { const profile = await this.userProfilesRepository.findOneByOrFail({ userId: flash.userId }); const meta = await this.metaService.fetch(); reply.header('Cache-Control', 'public, max-age=15'); + if (profile.preventAiLarning) { + reply.header('X-Robots-Tag', 'noimageai'); + reply.header('X-Robots-Tag', 'noai'); + } return await reply.view('flash', { flash: _flash, profile, @@ -554,6 +570,10 @@ export class ClientServerService { const profile = await this.userProfilesRepository.findOneByOrFail({ userId: clip.userId }); const meta = await this.metaService.fetch(); reply.header('Cache-Control', 'public, max-age=15'); + if (profile.preventAiLarning) { + reply.header('X-Robots-Tag', 'noimageai'); + reply.header('X-Robots-Tag', 'noai'); + } return await reply.view('clip', { clip: _clip, profile, @@ -576,6 +596,10 @@ export class ClientServerService { const profile = await this.userProfilesRepository.findOneByOrFail({ userId: post.userId }); const meta = await this.metaService.fetch(); reply.header('Cache-Control', 'public, max-age=15'); + if (profile.preventAiLarning) { + reply.header('X-Robots-Tag', 'noimageai'); + reply.header('X-Robots-Tag', 'noai'); + } return await reply.view('gallery-post', { post: _post, profile, From b545146bf9c1715b8064adcd07fc441ca41e238d Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 11:43:40 +0900 Subject: [PATCH 05/46] Update ja-JP.yml --- locales/ja-JP.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index f9e1e9559f..cfad313480 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1038,8 +1038,8 @@ thisChannelArchived: "このチャンネルはアーカイブされています displayOfNote: "ノートの表示" initialAccountSetting: "初期設定" youFollowing: "フォロー中" -preventAiLarning: "AIによる学習を防止" -preventAiLarningDescription: "投稿したノート、添付した画像などのコンテンツを学習の対象にしないようAIに要求します。これはnoaiフラグをHTMLレスポンスに含めることによって実現されます。" +preventAiLarning: "AIによる学習を拒否" +preventAiLarningDescription: "投稿したノートや画像などのコンテンツを学習の対象にしないようAIに要求します。これはnoaiフラグをHTMLレスポンスに含めることによって実現されます。この機能は実験的であり、AIによる学習を完全に防止するものではありません。" _initialAccountSetting: accountCreated: "アカウントの作成が完了しました!" From 0729678398eb12c2e5c8e7f156355e4ec53c9899 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 12:24:50 +0900 Subject: [PATCH 06/46] =?UTF-8?q?fix(frontend):=20=E3=83=96=E3=83=A9?= =?UTF-8?q?=E3=83=BC=E3=82=A8=E3=83=95=E3=82=A7=E3=82=AF=E3=83=88=E3=82=92?= =?UTF-8?q?=E6=9C=89=E5=8A=B9=E3=81=AB=E3=81=97=E3=81=A6=E3=81=84=E3=82=8B?= =?UTF-8?q?=E7=8A=B6=E6=85=8B=E3=81=A7=E9=AB=98=E8=B2=A0=E8=8D=B7=E3=81=AB?= =?UTF-8?q?=E3=81=AA=E3=82=8B=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 +- .../src/components/global/MkAvatar.vue | 20 +------------------ 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 301fe02ef5..767f98e8e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ - 投稿したコンテンツのAIによる学習を軽減するオプションを追加 ### Client -- +- Fix: ブラーエフェクトを有効にしている状態で高負荷になる問題を修正 ### Server - diff --git a/packages/frontend/src/components/global/MkAvatar.vue b/packages/frontend/src/components/global/MkAvatar.vue index ad36dcabe4..42abdcbdcc 100644 --- a/packages/frontend/src/components/global/MkAvatar.vue +++ b/packages/frontend/src/components/global/MkAvatar.vue @@ -2,7 +2,7 @@ -
+
@@ -154,24 +154,6 @@ watch(() => props.user.avatarBlurhash, () => { padding: 50%; pointer-events: none; - &.mask { - -webkit-mask: - url('data:image/svg+xml,') center / 50% 50%, - linear-gradient(#fff, #fff); - -webkit-mask-composite: destination-out, source-over; - mask: - url('data:image/svg+xml,') exclude center / 50% 50%, - linear-gradient(#fff, #fff); // polyfill of `image(#fff)` - - > .earLeft { - animation: eartightleft 6s infinite; - } - - > .earRight { - animation: eartightright 6s infinite; - } - } - > .earLeft, > .earRight { contain: strict; From 341c42ebb9c30428fdc7527dd3d22b2d25885ed6 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 15:05:08 +0900 Subject: [PATCH 07/46] enhance(backend): graceful shutdown for job queue and refactor --- packages/backend/src/core/QueueModule.ts | 41 ++++++- .../src/queue/DbQueueProcessorsService.ts | 69 ----------- .../ObjectStorageQueueProcessorsService.ts | 25 ---- .../backend/src/queue/QueueProcessorModule.ts | 8 -- .../src/queue/QueueProcessorService.ts | 108 +++++++++++++++--- .../RelationshipQueueProcessorsService.ts | 26 ----- .../src/queue/SystemQueueProcessorsService.ts | 37 ------ 7 files changed, 128 insertions(+), 186 deletions(-) delete mode 100644 packages/backend/src/queue/DbQueueProcessorsService.ts delete mode 100644 packages/backend/src/queue/ObjectStorageQueueProcessorsService.ts delete mode 100644 packages/backend/src/queue/RelationshipQueueProcessorsService.ts delete mode 100644 packages/backend/src/queue/SystemQueueProcessorsService.ts diff --git a/packages/backend/src/core/QueueModule.ts b/packages/backend/src/core/QueueModule.ts index d4905a5f88..1d73947776 100644 --- a/packages/backend/src/core/QueueModule.ts +++ b/packages/backend/src/core/QueueModule.ts @@ -1,4 +1,5 @@ -import { Module } from '@nestjs/common'; +import { setTimeout } from 'node:timers/promises'; +import { Inject, Module, OnApplicationShutdown } from '@nestjs/common'; import Bull from 'bull'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; @@ -41,9 +42,9 @@ export type SystemQueue = Bull.Queue>; export type EndedPollNotificationQueue = Bull.Queue; export type DeliverQueue = Bull.Queue; export type InboxQueue = Bull.Queue; -export type DbQueue = Bull.Queue>; +export type DbQueue = Bull.Queue; export type RelationshipQueue = Bull.Queue; -export type ObjectStorageQueue = Bull.Queue; +export type ObjectStorageQueue = Bull.Queue; export type WebhookDeliverQueue = Bull.Queue; const $system: Provider = { @@ -118,4 +119,36 @@ const $webhookDeliver: Provider = { $webhookDeliver, ], }) -export class QueueModule {} +export class QueueModule implements OnApplicationShutdown { + constructor( + @Inject('queue:system') public systemQueue: SystemQueue, + @Inject('queue:endedPollNotification') public endedPollNotificationQueue: EndedPollNotificationQueue, + @Inject('queue:deliver') public deliverQueue: DeliverQueue, + @Inject('queue:inbox') public inboxQueue: InboxQueue, + @Inject('queue:db') public dbQueue: DbQueue, + @Inject('queue:relationship') public relationshipQueue: RelationshipQueue, + @Inject('queue:objectStorage') public objectStorageQueue: ObjectStorageQueue, + @Inject('queue:webhookDeliver') public webhookDeliverQueue: WebhookDeliverQueue, + ) {} + + async onApplicationShutdown(signal: string): Promise { + if (process.env.NODE_ENV === 'test') { + // XXX: + // Shutting down the existing connections causes errors on Jest as + // Misskey has asynchronous postgres/redis connections that are not + // awaited. + // Let's wait for some random time for them to finish. + await setTimeout(5000); + } + await Promise.all([ + this.systemQueue.close(), + this.endedPollNotificationQueue.close(), + this.deliverQueue.close(), + this.inboxQueue.close(), + this.dbQueue.close(), + this.relationshipQueue.close(), + this.objectStorageQueue.close(), + this.webhookDeliverQueue.close(), + ]); + } +} diff --git a/packages/backend/src/queue/DbQueueProcessorsService.ts b/packages/backend/src/queue/DbQueueProcessorsService.ts deleted file mode 100644 index df8ac3a301..0000000000 --- a/packages/backend/src/queue/DbQueueProcessorsService.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; -import { bindThis } from '@/decorators.js'; -import { DeleteDriveFilesProcessorService } from './processors/DeleteDriveFilesProcessorService.js'; -import { ExportCustomEmojisProcessorService } from './processors/ExportCustomEmojisProcessorService.js'; -import { ExportNotesProcessorService } from './processors/ExportNotesProcessorService.js'; -import { ExportFollowingProcessorService } from './processors/ExportFollowingProcessorService.js'; -import { ExportMutingProcessorService } from './processors/ExportMutingProcessorService.js'; -import { ExportBlockingProcessorService } from './processors/ExportBlockingProcessorService.js'; -import { ExportUserListsProcessorService } from './processors/ExportUserListsProcessorService.js'; -import { ExportAntennasProcessorService } from './processors/ExportAntennasProcessorService.js'; -import { ImportFollowingProcessorService } from './processors/ImportFollowingProcessorService.js'; -import { ImportMutingProcessorService } from './processors/ImportMutingProcessorService.js'; -import { ImportBlockingProcessorService } from './processors/ImportBlockingProcessorService.js'; -import { ImportUserListsProcessorService } from './processors/ImportUserListsProcessorService.js'; -import { ImportCustomEmojisProcessorService } from './processors/ImportCustomEmojisProcessorService.js'; -import { ImportAntennasProcessorService } from './processors/ImportAntennasProcessorService.js'; -import { DeleteAccountProcessorService } from './processors/DeleteAccountProcessorService.js'; -import { ExportFavoritesProcessorService } from './processors/ExportFavoritesProcessorService.js'; -import type Bull from 'bull'; - -@Injectable() -export class DbQueueProcessorsService { - constructor( - @Inject(DI.config) - private config: Config, - - private deleteDriveFilesProcessorService: DeleteDriveFilesProcessorService, - private exportCustomEmojisProcessorService: ExportCustomEmojisProcessorService, - private exportNotesProcessorService: ExportNotesProcessorService, - private exportFavoritesProcessorService: ExportFavoritesProcessorService, - private exportFollowingProcessorService: ExportFollowingProcessorService, - private exportMutingProcessorService: ExportMutingProcessorService, - private exportBlockingProcessorService: ExportBlockingProcessorService, - private exportUserListsProcessorService: ExportUserListsProcessorService, - private exportAntennasProcessorService: ExportAntennasProcessorService, - private importFollowingProcessorService: ImportFollowingProcessorService, - private importMutingProcessorService: ImportMutingProcessorService, - private importBlockingProcessorService: ImportBlockingProcessorService, - private importUserListsProcessorService: ImportUserListsProcessorService, - private importCustomEmojisProcessorService: ImportCustomEmojisProcessorService, - private importAntennasProcessorService: ImportAntennasProcessorService, - private deleteAccountProcessorService: DeleteAccountProcessorService, - ) { - } - - @bindThis - public start(q: Bull.Queue): void { - q.process('deleteDriveFiles', (job, done) => this.deleteDriveFilesProcessorService.process(job, done)); - q.process('exportCustomEmojis', (job, done) => this.exportCustomEmojisProcessorService.process(job, done)); - q.process('exportNotes', (job, done) => this.exportNotesProcessorService.process(job, done)); - q.process('exportFavorites', (job, done) => this.exportFavoritesProcessorService.process(job, done)); - q.process('exportFollowing', (job, done) => this.exportFollowingProcessorService.process(job, done)); - q.process('exportMuting', (job, done) => this.exportMutingProcessorService.process(job, done)); - q.process('exportBlocking', (job, done) => this.exportBlockingProcessorService.process(job, done)); - q.process('exportUserLists', (job, done) => this.exportUserListsProcessorService.process(job, done)); - q.process('exportAntennas', (job, done) => this.exportAntennasProcessorService.process(job, done)); - q.process('importFollowing', (job, done) => this.importFollowingProcessorService.process(job, done)); - q.process('importFollowingToDb', (job) => this.importFollowingProcessorService.processDb(job)); - q.process('importMuting', (job, done) => this.importMutingProcessorService.process(job, done)); - q.process('importBlocking', (job, done) => this.importBlockingProcessorService.process(job, done)); - q.process('importBlockingToDb', (job) => this.importBlockingProcessorService.processDb(job)); - q.process('importUserLists', (job, done) => this.importUserListsProcessorService.process(job, done)); - q.process('importCustomEmojis', (job, done) => this.importCustomEmojisProcessorService.process(job, done)); - q.process('importAntennas', (job, done) => this.importAntennasProcessorService.process(job, done)); - q.process('deleteAccount', (job) => this.deleteAccountProcessorService.process(job)); - } -} diff --git a/packages/backend/src/queue/ObjectStorageQueueProcessorsService.ts b/packages/backend/src/queue/ObjectStorageQueueProcessorsService.ts deleted file mode 100644 index 865e47c3f8..0000000000 --- a/packages/backend/src/queue/ObjectStorageQueueProcessorsService.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; -import { CleanRemoteFilesProcessorService } from './processors/CleanRemoteFilesProcessorService.js'; -import { DeleteFileProcessorService } from './processors/DeleteFileProcessorService.js'; -import type Bull from 'bull'; -import { bindThis } from '@/decorators.js'; - -@Injectable() -export class ObjectStorageQueueProcessorsService { - constructor( - @Inject(DI.config) - private config: Config, - - private deleteFileProcessorService: DeleteFileProcessorService, - private cleanRemoteFilesProcessorService: CleanRemoteFilesProcessorService, - ) { - } - - @bindThis - public start(q: Bull.Queue): void { - q.process('deleteFile', 16, (job) => this.deleteFileProcessorService.process(job)); - q.process('cleanRemoteFiles', 16, (job, done) => this.cleanRemoteFilesProcessorService.process(job, done)); - } -} diff --git a/packages/backend/src/queue/QueueProcessorModule.ts b/packages/backend/src/queue/QueueProcessorModule.ts index 3d4cc77321..e1c6b93d9b 100644 --- a/packages/backend/src/queue/QueueProcessorModule.ts +++ b/packages/backend/src/queue/QueueProcessorModule.ts @@ -3,14 +3,10 @@ import { CoreModule } from '@/core/CoreModule.js'; import { GlobalModule } from '@/GlobalModule.js'; import { QueueLoggerService } from './QueueLoggerService.js'; import { QueueProcessorService } from './QueueProcessorService.js'; -import { DbQueueProcessorsService } from './DbQueueProcessorsService.js'; -import { RelationshipQueueProcessorsService } from './RelationshipQueueProcessorsService.js'; -import { ObjectStorageQueueProcessorsService } from './ObjectStorageQueueProcessorsService.js'; import { DeliverProcessorService } from './processors/DeliverProcessorService.js'; import { EndedPollNotificationProcessorService } from './processors/EndedPollNotificationProcessorService.js'; import { InboxProcessorService } from './processors/InboxProcessorService.js'; import { WebhookDeliverProcessorService } from './processors/WebhookDeliverProcessorService.js'; -import { SystemQueueProcessorsService } from './SystemQueueProcessorsService.js'; import { CheckExpiredMutingsProcessorService } from './processors/CheckExpiredMutingsProcessorService.js'; import { CleanChartsProcessorService } from './processors/CleanChartsProcessorService.js'; import { CleanProcessorService } from './processors/CleanProcessorService.js'; @@ -68,10 +64,6 @@ import { RelationshipProcessorService } from './processors/RelationshipProcessor DeleteFileProcessorService, CleanRemoteFilesProcessorService, RelationshipProcessorService, - SystemQueueProcessorsService, - ObjectStorageQueueProcessorsService, - DbQueueProcessorsService, - RelationshipQueueProcessorsService, WebhookDeliverProcessorService, EndedPollNotificationProcessorService, DeliverProcessorService, diff --git a/packages/backend/src/queue/QueueProcessorService.ts b/packages/backend/src/queue/QueueProcessorService.ts index 706110f6fc..dc025f9889 100644 --- a/packages/backend/src/queue/QueueProcessorService.ts +++ b/packages/backend/src/queue/QueueProcessorService.ts @@ -5,15 +5,36 @@ import type Logger from '@/logger.js'; import { QueueService } from '@/core/QueueService.js'; import { bindThis } from '@/decorators.js'; import { getJobInfo } from './get-job-info.js'; -import { SystemQueueProcessorsService } from './SystemQueueProcessorsService.js'; -import { ObjectStorageQueueProcessorsService } from './ObjectStorageQueueProcessorsService.js'; -import { DbQueueProcessorsService } from './DbQueueProcessorsService.js'; import { WebhookDeliverProcessorService } from './processors/WebhookDeliverProcessorService.js'; import { EndedPollNotificationProcessorService } from './processors/EndedPollNotificationProcessorService.js'; import { DeliverProcessorService } from './processors/DeliverProcessorService.js'; import { InboxProcessorService } from './processors/InboxProcessorService.js'; +import { DeleteDriveFilesProcessorService } from './processors/DeleteDriveFilesProcessorService.js'; +import { ExportCustomEmojisProcessorService } from './processors/ExportCustomEmojisProcessorService.js'; +import { ExportNotesProcessorService } from './processors/ExportNotesProcessorService.js'; +import { ExportFollowingProcessorService } from './processors/ExportFollowingProcessorService.js'; +import { ExportMutingProcessorService } from './processors/ExportMutingProcessorService.js'; +import { ExportBlockingProcessorService } from './processors/ExportBlockingProcessorService.js'; +import { ExportUserListsProcessorService } from './processors/ExportUserListsProcessorService.js'; +import { ExportAntennasProcessorService } from './processors/ExportAntennasProcessorService.js'; +import { ImportFollowingProcessorService } from './processors/ImportFollowingProcessorService.js'; +import { ImportMutingProcessorService } from './processors/ImportMutingProcessorService.js'; +import { ImportBlockingProcessorService } from './processors/ImportBlockingProcessorService.js'; +import { ImportUserListsProcessorService } from './processors/ImportUserListsProcessorService.js'; +import { ImportCustomEmojisProcessorService } from './processors/ImportCustomEmojisProcessorService.js'; +import { ImportAntennasProcessorService } from './processors/ImportAntennasProcessorService.js'; +import { DeleteAccountProcessorService } from './processors/DeleteAccountProcessorService.js'; +import { ExportFavoritesProcessorService } from './processors/ExportFavoritesProcessorService.js'; +import { CleanRemoteFilesProcessorService } from './processors/CleanRemoteFilesProcessorService.js'; +import { DeleteFileProcessorService } from './processors/DeleteFileProcessorService.js'; +import { RelationshipProcessorService } from './processors/RelationshipProcessorService.js'; +import { TickChartsProcessorService } from './processors/TickChartsProcessorService.js'; +import { ResyncChartsProcessorService } from './processors/ResyncChartsProcessorService.js'; +import { CleanChartsProcessorService } from './processors/CleanChartsProcessorService.js'; +import { CheckExpiredMutingsProcessorService } from './processors/CheckExpiredMutingsProcessorService.js'; +import { CleanProcessorService } from './processors/CleanProcessorService.js'; +import { AggregateRetentionProcessorService } from './processors/AggregateRetentionProcessorService.js'; import { QueueLoggerService } from './QueueLoggerService.js'; -import { RelationshipQueueProcessorsService } from './RelationshipQueueProcessorsService.js'; @Injectable() export class QueueProcessorService { @@ -25,14 +46,35 @@ export class QueueProcessorService { private queueLoggerService: QueueLoggerService, private queueService: QueueService, - private systemQueueProcessorsService: SystemQueueProcessorsService, - private objectStorageQueueProcessorsService: ObjectStorageQueueProcessorsService, - private dbQueueProcessorsService: DbQueueProcessorsService, - private relationshipQueueProcessorsService: RelationshipQueueProcessorsService, private webhookDeliverProcessorService: WebhookDeliverProcessorService, private endedPollNotificationProcessorService: EndedPollNotificationProcessorService, private deliverProcessorService: DeliverProcessorService, private inboxProcessorService: InboxProcessorService, + private deleteDriveFilesProcessorService: DeleteDriveFilesProcessorService, + private exportCustomEmojisProcessorService: ExportCustomEmojisProcessorService, + private exportNotesProcessorService: ExportNotesProcessorService, + private exportFavoritesProcessorService: ExportFavoritesProcessorService, + private exportFollowingProcessorService: ExportFollowingProcessorService, + private exportMutingProcessorService: ExportMutingProcessorService, + private exportBlockingProcessorService: ExportBlockingProcessorService, + private exportUserListsProcessorService: ExportUserListsProcessorService, + private exportAntennasProcessorService: ExportAntennasProcessorService, + private importFollowingProcessorService: ImportFollowingProcessorService, + private importMutingProcessorService: ImportMutingProcessorService, + private importBlockingProcessorService: ImportBlockingProcessorService, + private importUserListsProcessorService: ImportUserListsProcessorService, + private importCustomEmojisProcessorService: ImportCustomEmojisProcessorService, + private importAntennasProcessorService: ImportAntennasProcessorService, + private deleteAccountProcessorService: DeleteAccountProcessorService, + private deleteFileProcessorService: DeleteFileProcessorService, + private cleanRemoteFilesProcessorService: CleanRemoteFilesProcessorService, + private relationshipProcessorService: RelationshipProcessorService, + private tickChartsProcessorService: TickChartsProcessorService, + private resyncChartsProcessorService: ResyncChartsProcessorService, + private cleanChartsProcessorService: CleanChartsProcessorService, + private aggregateRetentionProcessorService: AggregateRetentionProcessorService, + private checkExpiredMutingsProcessorService: CheckExpiredMutingsProcessorService, + private cleanProcessorService: CleanProcessorService, ) { this.logger = this.queueLoggerService.logger; } @@ -119,14 +161,6 @@ export class QueueProcessorService { .on('error', (job: any, err: Error) => webhookLogger.error(`error ${err}`, { job, e: renderError(err) })) .on('stalled', (job) => webhookLogger.warn(`stalled ${getJobInfo(job)} to=${job.data.to}`)); - this.queueService.deliverQueue.process(this.config.deliverJobConcurrency ?? 128, (job) => this.deliverProcessorService.process(job)); - this.queueService.inboxQueue.process(this.config.inboxJobConcurrency ?? 16, (job) => this.inboxProcessorService.process(job)); - this.queueService.endedPollNotificationQueue.process((job, done) => this.endedPollNotificationProcessorService.process(job, done)); - this.queueService.webhookDeliverQueue.process(64, (job) => this.webhookDeliverProcessorService.process(job)); - this.dbQueueProcessorsService.start(this.queueService.dbQueue); - this.relationshipQueueProcessorsService.start(this.queueService.relationshipQueue); - this.objectStorageQueueProcessorsService.start(this.queueService.objectStorageQueue); - this.queueService.systemQueue.add('tickCharts', { }, { repeat: { cron: '55 * * * *' }, @@ -163,6 +197,46 @@ export class QueueProcessorService { removeOnComplete: true, }); - this.systemQueueProcessorsService.start(this.queueService.systemQueue); + this.queueService.deliverQueue.process(this.config.deliverJobConcurrency ?? 128, (job) => this.deliverProcessorService.process(job)); + this.queueService.inboxQueue.process(this.config.inboxJobConcurrency ?? 16, (job) => this.inboxProcessorService.process(job)); + this.queueService.endedPollNotificationQueue.process((job, done) => this.endedPollNotificationProcessorService.process(job, done)); + this.queueService.webhookDeliverQueue.process(64, (job) => this.webhookDeliverProcessorService.process(job)); + + this.queueService.dbQueue.process('deleteDriveFiles', (job, done) => this.deleteDriveFilesProcessorService.process(job, done)); + this.queueService.dbQueue.process('exportCustomEmojis', (job, done) => this.exportCustomEmojisProcessorService.process(job, done)); + this.queueService.dbQueue.process('exportNotes', (job, done) => this.exportNotesProcessorService.process(job, done)); + this.queueService.dbQueue.process('exportFavorites', (job, done) => this.exportFavoritesProcessorService.process(job, done)); + this.queueService.dbQueue.process('exportFollowing', (job, done) => this.exportFollowingProcessorService.process(job, done)); + this.queueService.dbQueue.process('exportMuting', (job, done) => this.exportMutingProcessorService.process(job, done)); + this.queueService.dbQueue.process('exportBlocking', (job, done) => this.exportBlockingProcessorService.process(job, done)); + this.queueService.dbQueue.process('exportUserLists', (job, done) => this.exportUserListsProcessorService.process(job, done)); + this.queueService.dbQueue.process('exportAntennas', (job, done) => this.exportAntennasProcessorService.process(job, done)); + this.queueService.dbQueue.process('importFollowing', (job, done) => this.importFollowingProcessorService.process(job, done)); + this.queueService.dbQueue.process('importFollowingToDb', (job) => this.importFollowingProcessorService.processDb(job)); + this.queueService.dbQueue.process('importMuting', (job, done) => this.importMutingProcessorService.process(job, done)); + this.queueService.dbQueue.process('importBlocking', (job, done) => this.importBlockingProcessorService.process(job, done)); + this.queueService.dbQueue.process('importBlockingToDb', (job) => this.importBlockingProcessorService.processDb(job)); + this.queueService.dbQueue.process('importUserLists', (job, done) => this.importUserListsProcessorService.process(job, done)); + this.queueService.dbQueue.process('importCustomEmojis', (job, done) => this.importCustomEmojisProcessorService.process(job, done)); + this.queueService.dbQueue.process('importAntennas', (job, done) => this.importAntennasProcessorService.process(job, done)); + this.queueService.dbQueue.process('deleteAccount', (job) => this.deleteAccountProcessorService.process(job)); + + this.queueService.objectStorageQueue.process('deleteFile', 16, (job) => this.deleteFileProcessorService.process(job)); + this.queueService.objectStorageQueue.process('cleanRemoteFiles', 16, (job, done) => this.cleanRemoteFilesProcessorService.process(job, done)); + + { + const maxJobs = this.config.relashionshipJobConcurrency ?? 16; + this.queueService.relationshipQueue.process('follow', maxJobs, (job) => this.relationshipProcessorService.processFollow(job)); + this.queueService.relationshipQueue.process('unfollow', maxJobs, (job) => this.relationshipProcessorService.processUnfollow(job)); + this.queueService.relationshipQueue.process('block', maxJobs, (job) => this.relationshipProcessorService.processBlock(job)); + this.queueService.relationshipQueue.process('unblock', maxJobs, (job) => this.relationshipProcessorService.processUnblock(job)); + } + + this.queueService.systemQueue.process('tickCharts', (job, done) => this.tickChartsProcessorService.process(job, done)); + this.queueService.systemQueue.process('resyncCharts', (job, done) => this.resyncChartsProcessorService.process(job, done)); + this.queueService.systemQueue.process('cleanCharts', (job, done) => this.cleanChartsProcessorService.process(job, done)); + this.queueService.systemQueue.process('aggregateRetention', (job, done) => this.aggregateRetentionProcessorService.process(job, done)); + this.queueService.systemQueue.process('checkExpiredMutings', (job, done) => this.checkExpiredMutingsProcessorService.process(job, done)); + this.queueService.systemQueue.process('clean', (job, done) => this.cleanProcessorService.process(job, done)); } } diff --git a/packages/backend/src/queue/RelationshipQueueProcessorsService.ts b/packages/backend/src/queue/RelationshipQueueProcessorsService.ts deleted file mode 100644 index 736b4fa80d..0000000000 --- a/packages/backend/src/queue/RelationshipQueueProcessorsService.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { bindThis } from '@/decorators.js'; -import { RelationshipProcessorService } from './processors/RelationshipProcessorService.js'; -import type Bull from 'bull'; -import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; - -@Injectable() -export class RelationshipQueueProcessorsService { - constructor( - @Inject(DI.config) - private config: Config, - - private relationshipProcessorService: RelationshipProcessorService, - ) { - } - - @bindThis - public start(q: Bull.Queue): void { - const maxJobs = this.config.relashionshipJobConcurrency ?? 16; - q.process('follow', maxJobs, (job) => this.relationshipProcessorService.processFollow(job)); - q.process('unfollow', maxJobs, (job) => this.relationshipProcessorService.processUnfollow(job)); - q.process('block', maxJobs, (job) => this.relationshipProcessorService.processBlock(job)); - q.process('unblock', maxJobs, (job) => this.relationshipProcessorService.processUnblock(job)); - } -} diff --git a/packages/backend/src/queue/SystemQueueProcessorsService.ts b/packages/backend/src/queue/SystemQueueProcessorsService.ts deleted file mode 100644 index 7fb0da4b10..0000000000 --- a/packages/backend/src/queue/SystemQueueProcessorsService.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; -import { bindThis } from '@/decorators.js'; -import { TickChartsProcessorService } from './processors/TickChartsProcessorService.js'; -import { ResyncChartsProcessorService } from './processors/ResyncChartsProcessorService.js'; -import { CleanChartsProcessorService } from './processors/CleanChartsProcessorService.js'; -import { CheckExpiredMutingsProcessorService } from './processors/CheckExpiredMutingsProcessorService.js'; -import { CleanProcessorService } from './processors/CleanProcessorService.js'; -import { AggregateRetentionProcessorService } from './processors/AggregateRetentionProcessorService.js'; -import type Bull from 'bull'; - -@Injectable() -export class SystemQueueProcessorsService { - constructor( - @Inject(DI.config) - private config: Config, - - private tickChartsProcessorService: TickChartsProcessorService, - private resyncChartsProcessorService: ResyncChartsProcessorService, - private cleanChartsProcessorService: CleanChartsProcessorService, - private aggregateRetentionProcessorService: AggregateRetentionProcessorService, - private checkExpiredMutingsProcessorService: CheckExpiredMutingsProcessorService, - private cleanProcessorService: CleanProcessorService, - ) { - } - - @bindThis - public start(q: Bull.Queue): void { - q.process('tickCharts', (job, done) => this.tickChartsProcessorService.process(job, done)); - q.process('resyncCharts', (job, done) => this.resyncChartsProcessorService.process(job, done)); - q.process('cleanCharts', (job, done) => this.cleanChartsProcessorService.process(job, done)); - q.process('aggregateRetention', (job, done) => this.aggregateRetentionProcessorService.process(job, done)); - q.process('checkExpiredMutings', (job, done) => this.checkExpiredMutingsProcessorService.process(job, done)); - q.process('clean', (job, done) => this.cleanProcessorService.process(job, done)); - } -} From 9557579b67c7e4ddedd300ffcd75dbaccc576fb9 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 15:30:36 +0900 Subject: [PATCH 08/46] =?UTF-8?q?fix(backend):=20=E3=83=86=E3=82=B9?= =?UTF-8?q?=E3=83=88=E6=99=82=E3=81=AF=E4=B8=80=E9=83=A8=E3=81=AE=E3=82=B5?= =?UTF-8?q?=E3=83=BC=E3=83=93=E3=82=B9=E3=82=92=E5=81=9C=E6=AD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/boot/common.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/backend/src/boot/common.ts b/packages/backend/src/boot/common.ts index 45ded5495c..3995545d7f 100644 --- a/packages/backend/src/boot/common.ts +++ b/packages/backend/src/boot/common.ts @@ -18,10 +18,12 @@ export async function server() { const serverService = app.get(ServerService); await serverService.launch(); - app.get(ChartManagementService).start(); - app.get(JanitorService).start(); - app.get(QueueStatsService).start(); - app.get(ServerStatsService).start(); + if (process.env.NODE_ENV !== 'test') { + app.get(ChartManagementService).start(); + app.get(JanitorService).start(); + app.get(QueueStatsService).start(); + app.get(ServerStatsService).start(); + } return app; } From adf66154d2f434636ad524b752c6c305db0ee74d Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 15:59:34 +0900 Subject: [PATCH 09/46] fix test --- packages/backend/test/e2e/users.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/test/e2e/users.ts b/packages/backend/test/e2e/users.ts index 7f556fddf2..640fa71a7b 100644 --- a/packages/backend/test/e2e/users.ts +++ b/packages/backend/test/e2e/users.ts @@ -371,7 +371,7 @@ describe('ユーザー', () => { assert.deepStrictEqual(response.pinnedNotes, []); assert.strictEqual(response.pinnedPageId, null); assert.strictEqual(response.pinnedPage, null); - assert.strictEqual(response.publicReactions, false); + assert.strictEqual(response.publicReactions, true); assert.strictEqual(response.ffVisibility, 'public'); assert.strictEqual(response.twoFactorEnabled, false); assert.strictEqual(response.usePasswordLessLogin, false); From d75a7fd42173e0c461feab02a22c7359f3c9ee1e Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 16:36:22 +0900 Subject: [PATCH 10/46] New Crowdin updates (#10815) * New translations ja-JP.yml (English) * New translations ja-JP.yml (German) * New translations ja-JP.yml (Korean) * New translations ja-JP.yml (Chinese Traditional) * New translations ja-JP.yml (Chinese Traditional) --- locales/de-DE.yml | 1 + locales/en-US.yml | 7 ++++--- locales/ko-KR.yml | 1 + locales/zh-TW.yml | 28 ++++++++++++++++++++++++++-- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/locales/de-DE.yml b/locales/de-DE.yml index d678fadd4a..a082130ac7 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -1040,6 +1040,7 @@ initialAccountSetting: "Kontoeinrichtung" youFollowing: "Gefolgt" _initialAccountSetting: accountCreated: "Dein Konto wurde erfolgreich erstellt!" + letsStartAccountSetup: "Lass uns nun dein Konto einrichten." letsFillYourProfile: "Lass uns zuerst dein Profil einrichten." profileSetting: "Profileinstellungen" theseSettingsCanEditLater: "Diese Einstellungen kannst du jederzeit ändern." diff --git a/locales/en-US.yml b/locales/en-US.yml index ea91bcc0e5..6d994cb297 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1036,20 +1036,21 @@ channelArchiveConfirmTitle: "Really archive {name}?" channelArchiveConfirmDescription: "An archived channel won't appear in the channel list or search results anymore. New posts can also not be added to it anymore." thisChannelArchived: "This channel has been archived." displayOfNote: "Note display" -initialAccountSetting: "Profile configuration" +initialAccountSetting: "Profile setup" youFollowing: "Followed" _initialAccountSetting: accountCreated: "Your account was successfully created!" + letsStartAccountSetup: "For starters, let's set up your profile." letsFillYourProfile: "First, let's set up your profile." profileSetting: "Profile settings" theseSettingsCanEditLater: "You can always change these settings later." youCanEditMoreSettingsInSettingsPageLater: "There are many more settings you can configure from the \"Settings\" page. Be sure to visit it later." followUsers: "Try following some users that interest you to build up your timeline." pushNotificationDescription: "Enabling push notifications will allow you to receive notifications from {name} directly on your device." - initialAccountSettingCompleted: "Profile configuration complete!" + initialAccountSettingCompleted: "Profile setup complete!" haveFun: "Enjoy {name}!" ifYouNeedLearnMore: "If you'd like to learn more about how to use {name} (Misskey), please visit {link}." - skipAreYouSure: "Really skip profile configuration?" + skipAreYouSure: "Really skip profile setup?" _serverRules: description: "A set of rules to be displayed before registration. Setting a summary of the Terms of Service is recommended." _accountMigration: diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index ef690d260b..672b589ca8 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -1240,6 +1240,7 @@ _achievements: title: "잠깐 쉬어" description: "클라이언트를 시작하고 30분이 경과하였습니다" _client60min: + title: "No \"Miss\" in Misskey" description: "클라이언트를 시작하고 60분이 경과하였습니다" _noteDeletedWithin1min: title: "있었는데요 없었습니다" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 4073b9629d..66ffebd6d3 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -1036,7 +1036,21 @@ channelArchiveConfirmTitle: "要封存{name}嗎?" channelArchiveConfirmDescription: "封存以後,在頻道列表與搜索結果中不會顯示,也無法發布新的貼文。" thisChannelArchived: "這個頻道已被封存。" displayOfNote: "顯示貼文" -youFollowing: "關注中" +initialAccountSetting: "初始設定" +youFollowing: "追隨中" +_initialAccountSetting: + accountCreated: "帳戶已建立完成!" + letsStartAccountSetup: "來進行帳戶的初始設定吧。" + letsFillYourProfile: "首先,來設定您的個人檔案吧。" + profileSetting: "個人檔案設定" + theseSettingsCanEditLater: "這裡的設定可以在之後變更。" + youCanEditMoreSettingsInSettingsPageLater: "除此之外,還可以在「設定」頁面進行各種設定。之後請確認看看。" + followUsers: "為了構築時間軸,試著追蹤您感興趣的使用者吧。" + pushNotificationDescription: "啟用推送通知,就可以在設備上接收{name}的通知。" + initialAccountSettingCompleted: "初始設定完成了!" + haveFun: "盡情享受{name}吧!" + ifYouNeedLearnMore: "關於如何使用{name}(Misskey)的詳細資訊,請見{link}。" + skipAreYouSure: "要略過初始設定嗎?" _serverRules: description: "設定伺服器的簡要規則,在新的註冊之前顯示。建議的內容是使用條款的摘要。" _accountMigration: @@ -1464,7 +1478,7 @@ _channel: removeBanner: "移除橫幅圖像" featured: "熱門貼文" owned: "管理中" - following: "關注中" + following: "追隨中" usersCount: "有{n}人參與" notesCount: "有{n}個貼文" nameAndDescription: "名稱與說明" @@ -1586,6 +1600,16 @@ _time: minute: "分鐘" hour: "小時" day: "日" +_timelineTutorial: + title: "Misskey的使用方法" + step1_1: "這個畫面是「時間軸」。發布到{name}的「貼文」按照時間順序顯示。" + step1_2: "時間軸有多種類型,例如在「首頁時間軸」中流動的是您追蹤的人的貼文;而在「本地時間軸」流動的是{name}全體的貼文。" + step2_1: "試試看,發布個貼文吧!按畫面上鉛筆圖示的按鈕開啟表格。" + step2_2: "初次貼文的內容,建議包括自我介紹以及「開始使用{name}」。" + step3_1: "貼文發出去了嗎?" + step3_2: "如果你的貼文出現在時間軸上,就代表發文成功。" + step4_1: "可以對貼文標記「反應」。" + step4_2: "點擊貼文的「+」圖示,即可選擇喜好的表情符號來標記反應。" _2fa: alreadyRegistered: "此設備已經被註冊過了" registerTOTP: "開始設定驗證應用程式" From 37c119e1f5b776b3eb3d9a165e5f68319b0612a6 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 17:45:13 +0900 Subject: [PATCH 11/46] refactor --- packages/frontend/src/components/MkWidgets.vue | 2 ++ packages/frontend/src/pages/explore.users.vue | 18 +++--------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/packages/frontend/src/components/MkWidgets.vue b/packages/frontend/src/components/MkWidgets.vue index 33e594acd8..ad1c02a488 100644 --- a/packages/frontend/src/components/MkWidgets.vue +++ b/packages/frontend/src/components/MkWidgets.vue @@ -32,6 +32,7 @@
+ + - - From 02059fdee41bb5a345eb8f93583cde62d79e1489 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 17:45:54 +0900 Subject: [PATCH 12/46] bump --- CHANGELOG.md | 5 +---- package.json | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 767f98e8e7..d2cdde81da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ --> -## 13.x.x (unreleased) +## 13.12.2 ### General - 投稿したコンテンツのAIによる学習を軽減するオプションを追加 @@ -20,9 +20,6 @@ ### Client - Fix: ブラーエフェクトを有効にしている状態で高負荷になる問題を修正 -### Server -- - ## 13.12.1 ### Client diff --git a/package.json b/package.json index 28e1cdcf1e..5379dcffa8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "13.12.1", + "version": "13.12.2", "codename": "nasubi", "repository": { "type": "git", From f9f115b66debc704292778b57b377e85c5371c20 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 17:49:30 +0900 Subject: [PATCH 13/46] refactor(frontend): use css module --- packages/frontend/src/components/MkRadio.vue | 95 +++++++++----------- 1 file changed, 43 insertions(+), 52 deletions(-) diff --git a/packages/frontend/src/components/MkRadio.vue b/packages/frontend/src/components/MkRadio.vue index 5db2f5ee6d..eea94d4692 100644 --- a/packages/frontend/src/components/MkRadio.vue +++ b/packages/frontend/src/components/MkRadio.vue @@ -1,8 +1,7 @@ @@ -39,8 +39,8 @@ function toggle(): void { } - From ed634b4b3d784244639ca0829064148239b66a40 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 17:53:01 +0900 Subject: [PATCH 14/46] refactor(frontend): use css module --- packages/frontend/src/components/MkSwitch.vue | 149 +++++++++--------- 1 file changed, 72 insertions(+), 77 deletions(-) diff --git a/packages/frontend/src/components/MkSwitch.vue b/packages/frontend/src/components/MkSwitch.vue index d9f6716f92..63738b6a44 100644 --- a/packages/frontend/src/components/MkSwitch.vue +++ b/packages/frontend/src/components/MkSwitch.vue @@ -1,21 +1,19 @@ @@ -45,52 +43,12 @@ const toggle = () => { }; - From ea9a95cd98bc4c4f337b99fe7e1b28b3781d14b3 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 17:53:49 +0900 Subject: [PATCH 15/46] delete unused component --- .../frontend/src/components/MkCheckbox.vue | 144 ------------------ 1 file changed, 144 deletions(-) delete mode 100644 packages/frontend/src/components/MkCheckbox.vue diff --git a/packages/frontend/src/components/MkCheckbox.vue b/packages/frontend/src/components/MkCheckbox.vue deleted file mode 100644 index a8e24dd839..0000000000 --- a/packages/frontend/src/components/MkCheckbox.vue +++ /dev/null @@ -1,144 +0,0 @@ - - - - - From c15b75e4774a10a2aad72ffb63dd74e1123ea57d Mon Sep 17 00:00:00 2001 From: nenohi Date: Wed, 10 May 2023 18:02:41 +0900 Subject: [PATCH 16/46] =?UTF-8?q?=E3=82=BB=E3=83=B3=E3=82=B7=E3=83=86?= =?UTF-8?q?=E3=82=A3=E3=83=96=E3=83=AF=E3=83=BC=E3=83=89=E3=82=92=E6=AD=A3?= =?UTF-8?q?=E8=A6=8F=E8=A1=A8=E7=8F=BE=E3=80=81CW=E3=81=AB=E3=82=82?= =?UTF-8?q?=E9=81=A9=E7=94=A8=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= =?UTF-8?q?=20(#10688)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * cwにセンシティブが効いてない * CWが無いときにTextを見るように * 比較演算子間違えた * とりあえずチェック * 正規表現対応 * /test/giにも対応 * matchでしなくてもいいのでは感 * レビュー修正 * Update packages/backend/src/core/NoteCreateService.ts Co-authored-by: Acid Chicken (硫酸鶏) * Update packages/backend/src/core/NoteCreateService.ts Co-authored-by: Acid Chicken (硫酸鶏) * 修正 * wipかも * wordsでスペース区切りのものできたかも * なんか動いたかも * test作成 * 文言の修正 * 修正 * note参照 --------- Co-authored-by: Acid Chicken (硫酸鶏) --- CHANGELOG.md | 1 + locales/ja-JP.yml | 1 + .../backend/src/core/NoteCreateService.ts | 29 +++++++++- packages/backend/test/e2e/note.ts | 55 +++++++++++++++++++ .../frontend/src/pages/admin/moderation.vue | 2 +- 5 files changed, 86 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2cdde81da..961e5fcca0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,7 @@ - カスタム絵文字のライセンスを複数でセットできるようになりました。 - 管理者が予約ユーザー名を設定できるようになりました。 - Fix: フォローリクエストの通知が残る問題を修正 +- センシティブワードの登録にAnd、正規表現が使用できるようになりました。 ### Client - アカウント作成時に初期設定ウィザードを表示するように diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index cfad313480..4f458dc4e3 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -990,6 +990,7 @@ rolesAssignedToMe: "自分に割り当てられたロール" resetPasswordConfirm: "パスワードリセットしますか?" sensitiveWords: "センシティブワード" sensitiveWordsDescription: "設定したワードが含まれるノートの公開範囲をホームにします。改行で区切って複数設定できます。" +sensitiveWordsDescription2: "スペースで区切るとAND指定になり、キーワードをスラッシュで囲むと正規表現になります。" notesSearchNotAvailable: "ノート検索は利用できません。" license: "ライセンス" unfavoriteConfirm: "お気に入り解除しますか?" diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 364976e4a7..977c9052c0 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -3,6 +3,7 @@ import * as mfm from 'mfm-js'; import { In, DataSource } from 'typeorm'; import * as Redis from 'ioredis'; import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; +import RE2 from 're2'; import { extractMentions } from '@/misc/extract-mentions.js'; import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm.js'; import { extractHashtags } from '@/misc/extract-hashtags.js'; @@ -238,7 +239,8 @@ export class NoteCreateService implements OnApplicationShutdown { if (data.channel != null) data.localOnly = true; if (data.visibility === 'public' && data.channel == null) { - if ((data.text != null) && (await this.metaService.fetch()).sensitiveWords.some(w => data.text!.includes(w))) { + const sensitiveWords = (await this.metaService.fetch()).sensitiveWords; + if (this.isSensitive(data, sensitiveWords)) { data.visibility = 'home'; } else if ((await this.roleService.getUserPolicies(user.id)).canPublicNote === false) { data.visibility = 'home'; @@ -670,6 +672,31 @@ export class NoteCreateService implements OnApplicationShutdown { // Register to search database this.index(note); } + + @bindThis + private isSensitive(note: Option, sensitiveWord: string[]): boolean { + if (sensitiveWord.length > 0) { + const text = note.cw ?? note.text ?? ''; + if (text === '') return false; + const matched = sensitiveWord.some(filter => { + // represents RegExp + const regexp = filter.match(/^\/(.+)\/(.*)$/); + // This should never happen due to input sanitisation. + if (!regexp) { + const words = filter.split(' '); + return words.every(keyword => text.includes(keyword)); + } + try { + return new RE2(regexp[1], regexp[2]).test(text); + } catch (err) { + // This should never happen due to input sanitisation. + return false; + } + }); + if (matched) return true; + } + return false; + } @bindThis private incRenoteCount(renote: Note) { diff --git a/packages/backend/test/e2e/note.ts b/packages/backend/test/e2e/note.ts index 9c851a5dd6..d2eb8f01d7 100644 --- a/packages/backend/test/e2e/note.ts +++ b/packages/backend/test/e2e/note.ts @@ -541,6 +541,61 @@ describe('Note', () => { assert.strictEqual(res.status, 400); }); + + test('センシティブな投稿はhomeになる (単語指定)', async () => { + const sensitive = await api('admin/update-meta', { + sensitiveWords: [ + "test", + ] + }, alice); + + assert.strictEqual(sensitive.status, 204); + + await new Promise(x => setTimeout(x, 2)); + + const note1 = await api('/notes/create', { + text: 'hogetesthuge', + }, alice); + + assert.strictEqual(note1.status, 200); + assert.strictEqual(note1.body.createdNote.visibility, 'home'); + + }); + + test('センシティブな投稿はhomeになる (正規表現)', async () => { + const sensitive = await api('admin/update-meta', { + sensitiveWords: [ + "/Test/i", + ] + }, alice); + + assert.strictEqual(sensitive.status, 204); + + const note2 = await api('/notes/create', { + text: 'hogetesthuge', + }, alice); + + assert.strictEqual(note2.status, 200); + assert.strictEqual(note2.body.createdNote.visibility, 'home'); + }); + + test('センシティブな投稿はhomeになる (スペースアンド)', async () => { + const sensitive = await api('admin/update-meta', { + sensitiveWords: [ + "Test hoge" + ] + }, alice); + + assert.strictEqual(sensitive.status, 204); + + const note2 = await api('/notes/create', { + text: 'hogeTesthuge', + }, alice); + + assert.strictEqual(note2.status, 200); + assert.strictEqual(note2.body.createdNote.visibility, 'home'); + + }); }); describe('notes/delete', () => { diff --git a/packages/frontend/src/pages/admin/moderation.vue b/packages/frontend/src/pages/admin/moderation.vue index ffd3b6e233..bf788e3609 100644 --- a/packages/frontend/src/pages/admin/moderation.vue +++ b/packages/frontend/src/pages/admin/moderation.vue @@ -27,7 +27,7 @@ - +
From 11ea1a28110fb735462dbe1dbceb1ca58e206f32 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 18:03:16 +0900 Subject: [PATCH 17/46] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 961e5fcca0..d680a6984f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ ### Client - Fix: ブラーエフェクトを有効にしている状態で高負荷になる問題を修正 +### Server +- センシティブワードの登録にAnd、正規表現が使用できるようになりました。 + ## 13.12.1 ### Client @@ -57,7 +60,6 @@ - カスタム絵文字のライセンスを複数でセットできるようになりました。 - 管理者が予約ユーザー名を設定できるようになりました。 - Fix: フォローリクエストの通知が残る問題を修正 -- センシティブワードの登録にAnd、正規表現が使用できるようになりました。 ### Client - アカウント作成時に初期設定ウィザードを表示するように From 6d4d9f417b75fb8021827db1bf66bf6c40af31d2 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 10 May 2023 18:26:02 +0900 Subject: [PATCH 18/46] New Crowdin updates (#10823) * New translations ja-JP.yml (English) * New translations ja-JP.yml (German) --- locales/de-DE.yml | 2 ++ locales/en-US.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/locales/de-DE.yml b/locales/de-DE.yml index a082130ac7..466872c0ad 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -1038,6 +1038,8 @@ thisChannelArchived: "Dieser Kanal wurde archiviert." displayOfNote: "Anzeige von Notizen" initialAccountSetting: "Kontoeinrichtung" youFollowing: "Gefolgt" +preventAiLarning: "Verwendung in machinellem Lernen (AI/KI) ablehnen" +preventAiLarningDescription: "Fordert Crawler auf, gepostetes Text- oder Bildmaterial usw. nicht in Datensätzen für maschinelles Lernen (AI/KI) zu verwenden. Dies wird durch das Hinzufügen eines \"noai\"-HTML-Tags an den jeweiligen Inhalt erreicht. Da dieser Tag jedoch ignoriert werden kann, ist eine vollständige Verhinderung hierdurch nicht möglich." _initialAccountSetting: accountCreated: "Dein Konto wurde erfolgreich erstellt!" letsStartAccountSetup: "Lass uns nun dein Konto einrichten." diff --git a/locales/en-US.yml b/locales/en-US.yml index 6d994cb297..1c472a36c0 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1038,6 +1038,8 @@ thisChannelArchived: "This channel has been archived." displayOfNote: "Note display" initialAccountSetting: "Profile setup" youFollowing: "Followed" +preventAiLarning: "Reject usage in Machine Learning (AI)" +preventAiLarningDescription: "Requests crawlers to not use posted text or image material etc. in machine learning (AI) data sets. This is achieved by adding a \"noai\" HTML-Tag to the respective content. A complete prevention can however not be achieved through this tag, as it may simply be ignored." _initialAccountSetting: accountCreated: "Your account was successfully created!" letsStartAccountSetup: "For starters, let's set up your profile." From 69afd0480e176b105ad1482c7fc72480ecd1b51a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Acid=20Chicken=20=28=E7=A1=AB=E9=85=B8=E9=B6=8F=29?= Date: Wed, 10 May 2023 10:33:49 +0000 Subject: [PATCH 19/46] ci: fix typo --- .github/workflows/storybook.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index eb6ace27da..05efbb12e6 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -20,7 +20,7 @@ jobs: fetch-depth: 0 submodules: true - name: Checkout HEAD - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request_target' run: git checkout ${{ github.head_ref }} - name: Install pnpm uses: pnpm/action-setup@v2 @@ -41,12 +41,12 @@ jobs: - name: Build storybook run: pnpm --filter frontend build-storybook - name: Publish to Chromatic - if: github.event_name != 'pull_request' && github.ref == 'refs/heads/master' + if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/master' run: pnpm --filter frontend chromatic --exit-once-uploaded -d storybook-static env: CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} - name: Publish to Chromatic - if: github.event_name != 'pull_request' && github.ref != 'refs/heads/master' + if: github.event_name != 'pull_request_target' && github.ref != 'refs/heads/master' id: chromatic_push run: | DIFF="${{ github.event.before }} HEAD" @@ -61,7 +61,7 @@ jobs: env: CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} - name: Publish to Chromatic - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request_target' id: chromatic_pull_request run: | DIFF="${{ github.base_ref }} HEAD" @@ -77,7 +77,7 @@ jobs: CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} - name: Notify that Chromatic will skip testing uses: actions/github-script@v6.4.0 - if: github.event_name == 'pull_request' && steps.chromatic_pull_request.outputs.skip == 'true' + if: github.event_name == 'pull_request_target' && steps.chromatic_pull_request.outputs.skip == 'true' with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | From 8c30ca50a86043c9ed7f0ff8c8eef9e4a8587e8e Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 11 May 2023 16:20:03 +0900 Subject: [PATCH 20/46] =?UTF-8?q?fix(frontend):=20=E3=82=88=E3=82=8A?= =?UTF-8?q?=E6=98=8E=E7=A2=BA=E3=81=AA=E8=AA=AC=E6=98=8E=E3=81=AB=E3=81=97?= =?UTF-8?q?=E3=81=9F=E3=81=AE=E3=81=A8typo=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/ja-JP.yml | 4 ++-- packages/frontend/src/pages/settings/privacy.vue | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 4f458dc4e3..66ecae8e64 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1039,8 +1039,8 @@ thisChannelArchived: "このチャンネルはアーカイブされています displayOfNote: "ノートの表示" initialAccountSetting: "初期設定" youFollowing: "フォロー中" -preventAiLarning: "AIによる学習を拒否" -preventAiLarningDescription: "投稿したノートや画像などのコンテンツを学習の対象にしないようAIに要求します。これはnoaiフラグをHTMLレスポンスに含めることによって実現されます。この機能は実験的であり、AIによる学習を完全に防止するものではありません。" +preventAiLearning: "生成AIによる学習を拒否" +preventAiLearningDescription: "外部の文章生成AIや画像生成AIに対して、投稿したノートや画像などのコンテンツを学習の対象にしないように要求します。これはnoaiフラグをHTMLレスポンスに含めることによって実現されますが、この要求に従うかはそのAI次第であるため、学習を完全に防止するものではありません。" _initialAccountSetting: accountCreated: "アカウントの作成が完了しました!" diff --git a/packages/frontend/src/pages/settings/privacy.vue b/packages/frontend/src/pages/settings/privacy.vue index 29a9efa2d7..4743b8c1a8 100644 --- a/packages/frontend/src/pages/settings/privacy.vue +++ b/packages/frontend/src/pages/settings/privacy.vue @@ -25,8 +25,8 @@ - {{ i18n.ts.preventAiLarning }}{{ i18n.ts.beta }} - + {{ i18n.ts.preventAiLearning }}{{ i18n.ts.beta }} + {{ i18n.ts.makeExplorable }} From b380dc53e13cd925eb94420863fe38f4779a6ab8 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 11 May 2023 16:22:46 +0900 Subject: [PATCH 21/46] fix typo --- packages/backend/migration/1683789676867-fix-typo.js | 11 +++++++++++ .../backend/src/core/entities/UserEntityService.ts | 2 +- packages/backend/src/models/entities/UserProfile.ts | 2 +- packages/backend/src/models/json-schema/user.ts | 2 +- .../src/server/api/endpoints/admin/show-user.ts | 2 +- .../backend/src/server/api/endpoints/i/update.ts | 4 ++-- .../backend/src/server/web/ClientServerService.ts | 12 ++++++------ packages/backend/src/server/web/views/clip.pug | 2 +- packages/backend/src/server/web/views/flash.pug | 2 +- .../backend/src/server/web/views/gallery-post.pug | 2 +- packages/backend/src/server/web/views/note.pug | 2 +- packages/backend/src/server/web/views/page.pug | 2 +- packages/backend/src/server/web/views/user.pug | 2 +- packages/backend/test/e2e/users.ts | 8 ++++---- packages/frontend/src/pages/settings/privacy.vue | 6 +++--- 15 files changed, 36 insertions(+), 25 deletions(-) create mode 100644 packages/backend/migration/1683789676867-fix-typo.js diff --git a/packages/backend/migration/1683789676867-fix-typo.js b/packages/backend/migration/1683789676867-fix-typo.js new file mode 100644 index 0000000000..c0dbbf0050 --- /dev/null +++ b/packages/backend/migration/1683789676867-fix-typo.js @@ -0,0 +1,11 @@ +export class FixTypo1683789676867 { + name = 'FixTypo1683789676867' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" RENAME COLUMN "preventAiLarning" TO "preventAiLearning"`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" RENAME COLUMN "preventAiLearning" TO "preventAiLarning"`); + } +} diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index cb0b15fac9..7f61e1d6f3 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -445,7 +445,7 @@ export class UserEntityService implements OnModuleInit { carefulBot: profile!.carefulBot, autoAcceptFollowed: profile!.autoAcceptFollowed, noCrawle: profile!.noCrawle, - preventAiLarning: profile!.preventAiLarning, + preventAiLearning: profile!.preventAiLearning, isExplorable: user.isExplorable, isDeleted: user.isDeleted, hideOnlineStatus: user.hideOnlineStatus, diff --git a/packages/backend/src/models/entities/UserProfile.ts b/packages/backend/src/models/entities/UserProfile.ts index 2cebc56096..236ee8f988 100644 --- a/packages/backend/src/models/entities/UserProfile.ts +++ b/packages/backend/src/models/entities/UserProfile.ts @@ -150,7 +150,7 @@ export class UserProfile { @Column('boolean', { default: true, }) - public preventAiLarning: boolean; + public preventAiLearning: boolean; @Column('boolean', { default: false, diff --git a/packages/backend/src/models/json-schema/user.ts b/packages/backend/src/models/json-schema/user.ts index 9d630db4cd..f9a20ac398 100644 --- a/packages/backend/src/models/json-schema/user.ts +++ b/packages/backend/src/models/json-schema/user.ts @@ -304,7 +304,7 @@ export const packedMeDetailedOnlySchema = { type: 'boolean', nullable: false, optional: false, }, - preventAiLarning: { + preventAiLearning: { type: 'boolean', nullable: false, optional: false, }, diff --git a/packages/backend/src/server/api/endpoints/admin/show-user.ts b/packages/backend/src/server/api/endpoints/admin/show-user.ts index 12e656a2f7..f49d2a0966 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-user.ts @@ -68,7 +68,7 @@ export default class extends Endpoint { emailVerified: profile.emailVerified, autoAcceptFollowed: profile.autoAcceptFollowed, noCrawle: profile.noCrawle, - preventAiLarning: profile.preventAiLarning, + preventAiLearning: profile.preventAiLearning, alwaysMarkNsfw: profile.alwaysMarkNsfw, autoSensitive: profile.autoSensitive, carefulBot: profile.carefulBot, diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index 4cc173c2d0..74be00a8b8 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -138,7 +138,7 @@ export const paramDef = { carefulBot: { type: 'boolean' }, autoAcceptFollowed: { type: 'boolean' }, noCrawle: { type: 'boolean' }, - preventAiLarning: { type: 'boolean' }, + preventAiLearning: { type: 'boolean' }, isBot: { type: 'boolean' }, isCat: { type: 'boolean' }, showTimelineReplies: { type: 'boolean' }, @@ -243,7 +243,7 @@ export default class extends Endpoint { if (typeof ps.carefulBot === 'boolean') profileUpdates.carefulBot = ps.carefulBot; if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed; if (typeof ps.noCrawle === 'boolean') profileUpdates.noCrawle = ps.noCrawle; - if (typeof ps.preventAiLarning === 'boolean') profileUpdates.preventAiLarning = ps.preventAiLarning; + if (typeof ps.preventAiLearning === 'boolean') profileUpdates.preventAiLearning = ps.preventAiLearning; if (typeof ps.isCat === 'boolean') updates.isCat = ps.isCat; if (typeof ps.injectFeaturedNote === 'boolean') profileUpdates.injectFeaturedNote = ps.injectFeaturedNote; if (typeof ps.receiveAnnouncementEmail === 'boolean') profileUpdates.receiveAnnouncementEmail = ps.receiveAnnouncementEmail; diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts index 12369c927c..f780280c1f 100644 --- a/packages/backend/src/server/web/ClientServerService.ts +++ b/packages/backend/src/server/web/ClientServerService.ts @@ -423,7 +423,7 @@ export class ClientServerService { : []; reply.header('Cache-Control', 'public, max-age=15'); - if (profile.preventAiLarning) { + if (profile.preventAiLearning) { reply.header('X-Robots-Tag', 'noimageai'); reply.header('X-Robots-Tag', 'noai'); } @@ -471,7 +471,7 @@ export class ClientServerService { const profile = await this.userProfilesRepository.findOneByOrFail({ userId: note.userId }); const meta = await this.metaService.fetch(); reply.header('Cache-Control', 'public, max-age=15'); - if (profile.preventAiLarning) { + if (profile.preventAiLearning) { reply.header('X-Robots-Tag', 'noimageai'); reply.header('X-Robots-Tag', 'noai'); } @@ -514,7 +514,7 @@ export class ClientServerService { } else { reply.header('Cache-Control', 'private, max-age=0, must-revalidate'); } - if (profile.preventAiLarning) { + if (profile.preventAiLearning) { reply.header('X-Robots-Tag', 'noimageai'); reply.header('X-Robots-Tag', 'noai'); } @@ -542,7 +542,7 @@ export class ClientServerService { const profile = await this.userProfilesRepository.findOneByOrFail({ userId: flash.userId }); const meta = await this.metaService.fetch(); reply.header('Cache-Control', 'public, max-age=15'); - if (profile.preventAiLarning) { + if (profile.preventAiLearning) { reply.header('X-Robots-Tag', 'noimageai'); reply.header('X-Robots-Tag', 'noai'); } @@ -570,7 +570,7 @@ export class ClientServerService { const profile = await this.userProfilesRepository.findOneByOrFail({ userId: clip.userId }); const meta = await this.metaService.fetch(); reply.header('Cache-Control', 'public, max-age=15'); - if (profile.preventAiLarning) { + if (profile.preventAiLearning) { reply.header('X-Robots-Tag', 'noimageai'); reply.header('X-Robots-Tag', 'noai'); } @@ -596,7 +596,7 @@ export class ClientServerService { const profile = await this.userProfilesRepository.findOneByOrFail({ userId: post.userId }); const meta = await this.metaService.fetch(); reply.header('Cache-Control', 'public, max-age=15'); - if (profile.preventAiLarning) { + if (profile.preventAiLearning) { reply.header('X-Robots-Tag', 'noimageai'); reply.header('X-Robots-Tag', 'noai'); } diff --git a/packages/backend/src/server/web/views/clip.pug b/packages/backend/src/server/web/views/clip.pug index 1491e0f748..74dc62f1e7 100644 --- a/packages/backend/src/server/web/views/clip.pug +++ b/packages/backend/src/server/web/views/clip.pug @@ -21,7 +21,7 @@ block og block meta if profile.noCrawle meta(name='robots' content='noindex') - if profile.preventAiLarning + if profile.preventAiLearning meta(name='robots' content='noimageai') meta(name='robots' content='noai') diff --git a/packages/backend/src/server/web/views/flash.pug b/packages/backend/src/server/web/views/flash.pug index 5005d27869..5594fcdfbf 100644 --- a/packages/backend/src/server/web/views/flash.pug +++ b/packages/backend/src/server/web/views/flash.pug @@ -21,7 +21,7 @@ block og block meta if profile.noCrawle meta(name='robots' content='noindex') - if profile.preventAiLarning + if profile.preventAiLearning meta(name='robots' content='noimageai') meta(name='robots' content='noai') diff --git a/packages/backend/src/server/web/views/gallery-post.pug b/packages/backend/src/server/web/views/gallery-post.pug index 2c1102ee79..10f2d269bc 100644 --- a/packages/backend/src/server/web/views/gallery-post.pug +++ b/packages/backend/src/server/web/views/gallery-post.pug @@ -21,7 +21,7 @@ block og block meta if user.host || profile.noCrawle meta(name='robots' content='noindex') - if profile.preventAiLarning + if profile.preventAiLearning meta(name='robots' content='noimageai') meta(name='robots' content='noai') diff --git a/packages/backend/src/server/web/views/note.pug b/packages/backend/src/server/web/views/note.pug index d768c4a46d..badfcccd61 100644 --- a/packages/backend/src/server/web/views/note.pug +++ b/packages/backend/src/server/web/views/note.pug @@ -22,7 +22,7 @@ block og block meta if user.host || isRenote || profile.noCrawle meta(name='robots' content='noindex') - if profile.preventAiLarning + if profile.preventAiLearning meta(name='robots' content='noimageai') meta(name='robots' content='noai') diff --git a/packages/backend/src/server/web/views/page.pug b/packages/backend/src/server/web/views/page.pug index 1dd95c52b8..ddffc361c8 100644 --- a/packages/backend/src/server/web/views/page.pug +++ b/packages/backend/src/server/web/views/page.pug @@ -21,7 +21,7 @@ block og block meta if profile.noCrawle meta(name='robots' content='noindex') - if profile.preventAiLarning + if profile.preventAiLearning meta(name='robots' content='noimageai') meta(name='robots' content='noai') diff --git a/packages/backend/src/server/web/views/user.pug b/packages/backend/src/server/web/views/user.pug index a5427d2ce0..f4c83aa89d 100644 --- a/packages/backend/src/server/web/views/user.pug +++ b/packages/backend/src/server/web/views/user.pug @@ -20,7 +20,7 @@ block og block meta if user.host || profile.noCrawle meta(name='robots' content='noindex') - if profile.preventAiLarning + if profile.preventAiLearning meta(name='robots' content='noimageai') meta(name='robots' content='noai') diff --git a/packages/backend/test/e2e/users.ts b/packages/backend/test/e2e/users.ts index 640fa71a7b..a7f8210c8e 100644 --- a/packages/backend/test/e2e/users.ts +++ b/packages/backend/test/e2e/users.ts @@ -145,7 +145,7 @@ describe('ユーザー', () => { carefulBot: user.carefulBot, autoAcceptFollowed: user.autoAcceptFollowed, noCrawle: user.noCrawle, - preventAiLarning: user.preventAiLarning, + preventAiLearning: user.preventAiLearning, isExplorable: user.isExplorable, isDeleted: user.isDeleted, hideOnlineStatus: user.hideOnlineStatus, @@ -391,7 +391,7 @@ describe('ユーザー', () => { assert.strictEqual(response.carefulBot, false); assert.strictEqual(response.autoAcceptFollowed, true); assert.strictEqual(response.noCrawle, false); - assert.strictEqual(response.preventAiLarning, true); + assert.strictEqual(response.preventAiLearning, true); assert.strictEqual(response.isExplorable, true); assert.strictEqual(response.isDeleted, false); assert.strictEqual(response.hideOnlineStatus, false); @@ -464,8 +464,8 @@ describe('ユーザー', () => { { parameters: (): object => ({ autoAcceptFollowed: false }) }, { parameters: (): object => ({ noCrawle: true }) }, { parameters: (): object => ({ noCrawle: false }) }, - { parameters: (): object => ({ preventAiLarning: false }) }, - { parameters: (): object => ({ preventAiLarning: true }) }, + { parameters: (): object => ({ preventAiLearning: false }) }, + { parameters: (): object => ({ preventAiLearning: true }) }, { parameters: (): object => ({ isBot: true }) }, { parameters: (): object => ({ isBot: false }) }, { parameters: (): object => ({ isCat: true }) }, diff --git a/packages/frontend/src/pages/settings/privacy.vue b/packages/frontend/src/pages/settings/privacy.vue index 4743b8c1a8..a1af0ba80b 100644 --- a/packages/frontend/src/pages/settings/privacy.vue +++ b/packages/frontend/src/pages/settings/privacy.vue @@ -24,7 +24,7 @@ {{ i18n.ts.noCrawle }} - + {{ i18n.ts.preventAiLearning }}{{ i18n.ts.beta }} @@ -75,7 +75,7 @@ import { definePageMetadata } from '@/scripts/page-metadata'; let isLocked = $ref($i.isLocked); let autoAcceptFollowed = $ref($i.autoAcceptFollowed); let noCrawle = $ref($i.noCrawle); -let preventAiLarning = $ref($i.preventAiLarning); +let preventAiLearning = $ref($i.preventAiLearning); let isExplorable = $ref($i.isExplorable); let hideOnlineStatus = $ref($i.hideOnlineStatus); let publicReactions = $ref($i.publicReactions); @@ -91,7 +91,7 @@ function save() { isLocked: !!isLocked, autoAcceptFollowed: !!autoAcceptFollowed, noCrawle: !!noCrawle, - preventAiLarning: !!preventAiLarning, + preventAiLearning: !!preventAiLearning, isExplorable: !!isExplorable, hideOnlineStatus: !!hideOnlineStatus, publicReactions: !!publicReactions, From 177359689e09732b6e839cd090872a17298310f3 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 11 May 2023 16:26:35 +0900 Subject: [PATCH 22/46] =?UTF-8?q?fix(frontend):=20=E3=82=AB=E3=83=A9?= =?UTF-8?q?=E3=83=BC=E3=83=90=E3=83=BC=E3=81=8C=E3=83=AA=E3=83=97=E3=83=A9?= =?UTF-8?q?=E3=82=A4=E3=81=AB=E3=81=AF=E8=A1=A8=E7=A4=BA=E3=81=95=E3=82=8C?= =?UTF-8?q?=E3=81=AA=E3=81=84=E3=81=AE=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + packages/frontend/src/components/MkNoteSub.vue | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d680a6984f..45fce4977c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ ### Client - Fix: ブラーエフェクトを有効にしている状態で高負荷になる問題を修正 +- Fix: カラーバーがリプライには表示されないのを修正 ### Server - センシティブワードの登録にAnd、正規表現が使用できるようになりました。 diff --git a/packages/frontend/src/components/MkNoteSub.vue b/packages/frontend/src/components/MkNoteSub.vue index c293641355..9ac0b7858f 100644 --- a/packages/frontend/src/components/MkNoteSub.vue +++ b/packages/frontend/src/components/MkNoteSub.vue @@ -1,6 +1,7 @@ + -