From 41f664bed978acfcbd4fde02513bafb163e0351a Mon Sep 17 00:00:00 2001 From: atsu1125 Date: Fri, 16 Dec 2022 03:01:29 +0900 Subject: [PATCH] Feat: AvoidSearchIndex --- locales/en-US.yml | 1 + locales/ja-JP.yml | 1 + migration/1671119579013-avoidsearchindex.ts | 14 ++++++++++++++ .../common/views/components/settings/profile.vue | 6 +++++- src/models/entities/user.ts | 5 +++++ src/models/repositories/user.ts | 1 + src/server/api/endpoints/i/update.ts | 8 ++++++++ src/server/web/index.ts | 4 +++- src/server/web/views/base.pug | 3 +++ src/server/web/views/note.pug | 2 +- src/server/web/views/page.pug | 2 +- src/server/web/views/user.pug | 2 +- 12 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 migration/1671119579013-avoidsearchindex.ts diff --git a/locales/en-US.yml b/locales/en-US.yml index 53daafde48..9dc68c868a 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -808,6 +808,7 @@ common/views/components/profile-editor.vue: careful-bot: "Follower requests from bots require approval" careful-remote: "Follower requests from remote require approval" auto-accept-followed: "Automatically approve follows from the people you follow" + avoid-search-index: "Avoid search engine index" advanced: "Other" privacy: "Privacy" save: "Save" diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index c4af183857..632ded97cc 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -871,6 +871,7 @@ common/views/components/profile-editor.vue: careful-bot: "Bot からのフォローだけ承認制にする" careful-remote: "リモートからのフォローだけ承認制にする" auto-accept-followed: "フォローしているユーザーからのフォローを自動承認する" + avoid-search-index: "検索エンジンによるインデックスを避ける" advanced: "その他" privacy: "プライバシー" save: "保存" diff --git a/migration/1671119579013-avoidsearchindex.ts b/migration/1671119579013-avoidsearchindex.ts new file mode 100644 index 0000000000..f1a3fac2a3 --- /dev/null +++ b/migration/1671119579013-avoidsearchindex.ts @@ -0,0 +1,14 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class avoidsearchindex1671119579013 implements MigrationInterface { + name = 'avoidsearchindex1671119579013' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" ADD "avoidSearchIndex" boolean NOT NULL DEFAULT false`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "avoidSearchIndex"`); + } + +} diff --git a/src/client/app/common/views/components/settings/profile.vue b/src/client/app/common/views/components/settings/profile.vue index abfc9ebb88..dff147ed2f 100644 --- a/src/client/app/common/views/components/settings/profile.vue +++ b/src/client/app/common/views/components/settings/profile.vue @@ -93,6 +93,7 @@ {{ $t('careful-bot') }} {{ $t('careful-remote') }} {{ $t('auto-accept-followed') }} + {{ $t('avoid-search-index') }} @@ -178,6 +179,7 @@ export default Vue.extend({ carefulBot: false, carefulRemote: false, autoAcceptFollowed: false, + avoidSearchIndex: false, saving: false, avatarUploading: false, bannerUploading: false, @@ -220,6 +222,7 @@ export default Vue.extend({ this.carefulBot = this.$store.state.i.carefulBot; this.carefulRemote = this.$store.state.i.carefulRemote; this.autoAcceptFollowed = this.$store.state.i.autoAcceptFollowed; + this.avoidSearchIndex = this.$store.state.i.avoidSearchIndex; this.fieldName0 = this.$store.state.i.fields[0] ? this.$store.state.i.fields[0].name : null; this.fieldValue0 = this.$store.state.i.fields[0] ? this.$store.state.i.fields[0].value : null; @@ -300,7 +303,8 @@ export default Vue.extend({ isLocked: !!this.isLocked, carefulBot: !!this.carefulBot, carefulRemote: !!this.carefulRemote, - autoAcceptFollowed: !!this.autoAcceptFollowed + autoAcceptFollowed: !!this.autoAcceptFollowed, + avoidSearchIndex: !!this.avoidSearchIndex, }).then(i => { this.saving = false; this.$store.state.i.avatarId = i.avatarId; diff --git a/src/models/entities/user.ts b/src/models/entities/user.ts index 3fa28eeb8e..f0435ffa85 100644 --- a/src/models/entities/user.ts +++ b/src/models/entities/user.ts @@ -211,6 +211,11 @@ export class User { @JoinColumn() public movedToUser: User | null; + @Column('boolean', { + default: false, + }) + public avoidSearchIndex: boolean; + constructor(data: Partial) { if (data == null) return; diff --git a/src/models/repositories/user.ts b/src/models/repositories/user.ts index 7e52e2ce6d..3fb0766cf5 100644 --- a/src/models/repositories/user.ts +++ b/src/models/repositories/user.ts @@ -153,6 +153,7 @@ export class UserRepository extends Repository { isCat: user.isCat || falsy, isVerified: user.isVerified || falsy, isPremium: user.isPremium || falsy, + avoidSearchIndex: user.avoidSearchIndex || falsy, // カスタム絵文字添付 emojis: populateEmojis(user.emojis, user.host), diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts index 1b563d386e..3872354d68 100644 --- a/src/server/api/endpoints/i/update.ts +++ b/src/server/api/endpoints/i/update.ts @@ -113,6 +113,13 @@ export const meta = { } }, + avoidSearchIndex: { + validator: $.optional.bool, + desc: { + 'ja-JP': '検索エンジンによるインデックスを避けるか' + } + }, + isBot: { validator: $.optional.bool, desc: { @@ -202,6 +209,7 @@ export default define(meta, async (ps, user, app) => { if (typeof ps.carefulBot == 'boolean') profileUpdates.carefulBot = ps.carefulBot; if (typeof ps.carefulRemote == 'boolean') profileUpdates.carefulRemote = ps.carefulRemote; if (typeof ps.autoAcceptFollowed == 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed; + if (typeof ps.avoidSearchIndex == 'boolean') updates.avoidSearchIndex = ps.avoidSearchIndex; if (typeof ps.isCat == 'boolean') updates.isCat = ps.isCat; if (typeof ps.autoWatch == 'boolean') profileUpdates.autoWatch = ps.autoWatch; if (typeof ps.alwaysMarkNsfw == 'boolean') profileUpdates.alwaysMarkNsfw = ps.alwaysMarkNsfw; diff --git a/src/server/web/index.ts b/src/server/web/index.ts index 111b192843..05fc701ccf 100644 --- a/src/server/web/index.ts +++ b/src/server/web/index.ts @@ -311,12 +311,14 @@ router.get('/streaming', async ctx => { // Render base html for all requests router.get('*', async ctx => { const meta = await fetchMeta(); + const noindex = ctx.path.match(/^[/](search|tags[/]|explore|featured)/); await ctx.render('base', { img: meta.bannerUrl, title: meta.name || 'Misskey', instanceName: meta.name || 'Misskey', desc: meta.description, - icon: meta.iconUrl + icon: meta.iconUrl, + noindex }); ctx.set('Cache-Control', 'public, max-age=300'); }); diff --git a/src/server/web/views/base.pug b/src/server/web/views/base.pug index 7ec6f36336..c8aacbd315 100644 --- a/src/server/web/views/base.pug +++ b/src/server/web/views/base.pug @@ -17,6 +17,9 @@ html link(rel='apple-touch-icon' href= icon || '/apple-touch-icon.png') link(rel='manifest' href='/manifest.json') + if noindex + meta(name='robots' content='noindex') + title block title = title || 'Areionskey' diff --git a/src/server/web/views/note.pug b/src/server/web/views/note.pug index 85367755f4..08b421fc3d 100644 --- a/src/server/web/views/note.pug +++ b/src/server/web/views/note.pug @@ -26,7 +26,7 @@ block meta meta(name='twitter:card' content='summary') // todo - if user.host + if user.host || user.avoidSearchIndex meta(name='robots' content='noindex') if user.twitter diff --git a/src/server/web/views/page.pug b/src/server/web/views/page.pug index a67a3eeabc..a17352f3d5 100644 --- a/src/server/web/views/page.pug +++ b/src/server/web/views/page.pug @@ -25,7 +25,7 @@ block meta meta(name='twitter:card' content='summary') - if user.host + if user.host || user.avoidSearchIndex meta(name='robots' content='noindex') // todo diff --git a/src/server/web/views/user.pug b/src/server/web/views/user.pug index d41b0bbac0..e2e0e13f2b 100644 --- a/src/server/web/views/user.pug +++ b/src/server/web/views/user.pug @@ -24,7 +24,7 @@ block meta meta(name='twitter:card' content='summary') - if user.host + if user.host || user.avoidSearchIndex meta(name='robots' content='noindex') if profile.twitter