Skip to content

Commit

Permalink
feat: isSensitiveなUser (#112)
Browse files Browse the repository at this point in the history
* feat: isSensitiveなUser

* feat: センシティブなユーザーである場合警告を出すように

* enhance: センシティブなユーザーは検索結果から除外するように

* enhance: センシティブなユーザーが投稿する際には常にCWを投稿フォームで付与するように

---------

Co-authored-by: Esurio <esurio@esurio1673.net>
  • Loading branch information
1673beta and Esurio authored Jul 31, 2024
1 parent e3f76de commit 1a6fa7e
Show file tree
Hide file tree
Showing 17 changed files with 106 additions and 1 deletion.
12 changes: 12 additions & 0 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,14 @@ export interface Locale extends ILocale {
* にゃにゃにゃ??
*/
"flagAsCatDescription": string;
/**
* センシティブとして設定
*/
"flagAsSensitive": string;
/**
* このオプションを有効にすると、このアカウントはセンシティブなアカウントとして他者に表示されます。この機能を有効にすると、検索結果に表示されなくなります。現在ローカル限定の機能です。
*/
"flagAsSensitiveDescription": string;
/**
* タイムラインにノートへの返信を表示する
*/
Expand Down Expand Up @@ -1546,6 +1554,10 @@ export interface Locale extends ILocale {
* リモートユーザーのため、情報が不完全です。
*/
"remoteUserCaution": string;
/**
* センシティブなユーザーです。
*/
"sensitiveUserCaution": string;
/**
* アクティビティ
*/
Expand Down
3 changes: 3 additions & 0 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ flagAsBot: "Botとして設定"
flagAsBotDescription: "このアカウントがプログラムによって運用される場合は、このフラグをオンにします。オンにすると、反応の連鎖を防ぐためのフラグとして他の開発者に役立ったり、CherryPickのシステム上での扱いがBotに合ったものになります。"
flagAsCat: "にゃああああああああああああああ!!!!!!!!!!!!"
flagAsCatDescription: "にゃにゃにゃ??"
flagAsSensitive: "センシティブとして設定"
flagAsSensitiveDescription: "このオプションを有効にすると、このアカウントはセンシティブなアカウントとして他者に表示されます。この機能を有効にすると、検索結果に表示されなくなります。現在ローカル限定の機能です。"
flagShowTimelineReplies: "タイムラインにノートへの返信を表示する"
flagShowTimelineRepliesDescription: "オンにすると、タイムラインにユーザーのノート以外にもそのユーザーの他のノートへの返信を表示します。"
autoAcceptFollowed: "フォロー中ユーザーからのフォロリクを自動承認"
Expand Down Expand Up @@ -381,6 +383,7 @@ termsOfService: "利用規約"
start: "始める"
home: "ホーム"
remoteUserCaution: "リモートユーザーのため、情報が不完全です。"
sensitiveUserCaution: "センシティブなユーザーです。"
activity: "アクティビティ"
images: "画像"
image: "画像"
Expand Down
11 changes: 11 additions & 0 deletions packages/backend/migration/1722350613009-AddIsSensitive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export class AddIsSensitive1722350613009 {
name = 'AddIsSensitive1722350613009'

async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "user" ADD "isSensitive" boolean NOT NULL DEFAULT false`);
}

async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isSensitive"`);
}
}
11 changes: 11 additions & 0 deletions packages/backend/migration/1722353293595-AddSensitiveProfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export class AddSensitiveProfile1722353293595 {
name = 'AddSensitiveProfile1722353293595'

async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "user_profile" ADD "isSensitive" boolean NOT NULL DEFAULT false`);
}

async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "isSensitive"`);
}
}
2 changes: 2 additions & 0 deletions packages/backend/src/core/NoteCreateService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ export class NoteCreateService implements OnApplicationShutdown {
isBot: MiUser['isBot'];
isCat: MiUser['isCat'];
isIndexable: MiUser['isIndexable'];
isSensitive: MiUser['isSensitive'];
}, data: Option, silent = false): Promise<MiNote> {
// チャンネル外にリプライしたら対象のスコープに合わせる
// (クライアントサイドでやっても良い処理だと思うけどとりあえずサーバーサイドで)
Expand Down Expand Up @@ -537,6 +538,7 @@ export class NoteCreateService implements OnApplicationShutdown {
host: MiUser['host'];
isBot: MiUser['isBot'];
isIndexable: MiUser['isIndexable'];
isSensitive: MiUser['isSensitive'];
}, data: Option, silent: boolean, tags: string[], mentionedUsers: MinimumUser[]) {
const meta = await this.metaService.fetch();

Expand Down
2 changes: 2 additions & 0 deletions packages/backend/src/core/NoteUpdateService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export class NoteUpdateService implements OnApplicationShutdown {
host: MiUser['host'];
isBot: MiUser['isBot'];
isIndexable: MiUser['isIndexable'];
isSensitive: MiUser['isSensitive'];
}, data: Option, note: MiNote, silent = false): Promise<MiNote | null> {
if (data.updatedAt == null) data.updatedAt = new Date();

Expand Down Expand Up @@ -213,6 +214,7 @@ export class NoteUpdateService implements OnApplicationShutdown {
host: MiUser['host'];
isBot: MiUser['isBot'];
isIndexable: MiUser['isIndexable'];
isSensitive: MiUser['isSensitive'];
}, silent: boolean) {
if (!silent) {
if (this.userEntityService.isLocalUser(user)) this.activeUsersChart.write(user);
Expand Down
3 changes: 2 additions & 1 deletion packages/backend/src/core/SearchService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ export class SearchService {
.leftJoinAndSelect('note.renote', 'renote')
.leftJoinAndSelect('reply.user', 'replyUser')
.leftJoinAndSelect('renote.user', 'renoteUser')
.andWhere('user.isIndexable = true');
.andWhere('user.isIndexable = true')
.andWhere('user.isSensitive = false');

if (opts.host) {
if (opts.host === '.') {
Expand Down
2 changes: 2 additions & 0 deletions packages/backend/src/core/entities/UserEntityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,7 @@ export class UserEntityService implements OnModuleInit {
isBot: user.isBot,
isCat: user.isCat,
isIndexable: user.isIndexable,
isSensitive: user.isSensitive,
instance: user.host ? this.federatedInstanceService.federatedInstanceCache.fetch(user.host).then(instance => instance ? {
name: instance.name,
softwareName: instance.softwareName,
Expand Down Expand Up @@ -568,6 +569,7 @@ export class UserEntityService implements OnModuleInit {
isLocked: user.isLocked,
isSilenced: this.roleService.getUserPolicies(user.id).then(r => !r.canPublicNote),
isSuspended: user.isSuspended,
isSensitive: user.isSensitive,
description: profile!.description,
location: profile!.location,
birthday: profile!.birthday,
Expand Down
7 changes: 7 additions & 0 deletions packages/backend/src/models/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,13 @@ export class MiUser {
})
public isIndexable: boolean;

@Index()
@Column('boolean', {
default: false,
comment: 'Whether the User is sensitive.',
})
public isSensitive: boolean;

constructor(data: Partial<MiUser>) {
if (data == null) return;

Expand Down
6 changes: 6 additions & 0 deletions packages/backend/src/models/UserProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,12 @@ export class MiUserProfile {
})
public isIndexable: boolean;

@Column('boolean', {
default: false,
comment: 'Whether User is sensitive.',
})
public isSensitive: boolean;

@Column('boolean', {
default: true,
})
Expand Down
9 changes: 9 additions & 0 deletions packages/backend/src/models/json-schema/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,11 @@ export const packedUserDetailedNotMeOnlySchema = {
nullable: false, optional: false,
example: false,
},
isSensitive: {
type: 'boolean',
nullable: false, optional: false,
example: false,
},
description: {
type: 'string',
nullable: true, optional: false,
Expand Down Expand Up @@ -493,6 +498,10 @@ export const packedMeDetailedOnlySchema = {
type: 'boolean',
nullable: false, optional: false,
},
isSensitive: {
type: 'boolean',
nullable: false, optional: false,
},
isDeleted: {
type: 'boolean',
nullable: false, optional: false,
Expand Down
5 changes: 5 additions & 0 deletions packages/backend/src/server/api/endpoints/i/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ export const paramDef = {
noCrawle: { type: 'boolean' },
preventAiLearning: { type: 'boolean' },
isIndexable: { type: 'boolean' },
isSensitive: { type: 'boolean' },
isBot: { type: 'boolean' },
isCat: { type: 'boolean' },
injectFeaturedNote: { type: 'boolean' },
Expand Down Expand Up @@ -329,6 +330,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
updates.isIndexable = ps.isIndexable;
profileUpdates.isIndexable = ps.isIndexable;
};
if (typeof ps.isSensitive === 'boolean') {
updates.isSensitive = ps.isSensitive;
profileUpdates.isSensitive = ps.isSensitive;
};
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;
Expand Down
4 changes: 4 additions & 0 deletions packages/cherrypick-js/src/autogen/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4033,6 +4033,8 @@ export type components = {
isSilenced: boolean;
/** @example false */
isSuspended: boolean;
/** @example false */
isSensitive: boolean;
/** @example Hi masters, I am Ai! */
description: string | null;
location: string | null;
Expand Down Expand Up @@ -4095,6 +4097,7 @@ export type components = {
preventAiLearning: boolean;
isExplorable: boolean;
isIndexable: boolean;
isSensitive: boolean;
isDeleted: boolean;
/** @enum {string} */
twoFactorBackupCodesStock: 'full' | 'partial' | 'none';
Expand Down Expand Up @@ -20451,6 +20454,7 @@ export type operations = {
noCrawle?: boolean;
preventAiLearning?: boolean;
isIndexable?: boolean;
isSensitive?: boolean;
isBot?: boolean;
isCat?: boolean;
injectFeaturedNote?: boolean;
Expand Down
6 changes: 6 additions & 0 deletions packages/frontend/src/components/MkPostForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ import { vibrate } from '@/scripts/vibrate.js';
import * as sound from '@/scripts/sound.js';
import { mfmFunctionPicker } from '@/scripts/mfm-function-picker.js';
const $i = signinRequired();
const modal = inject('modal');
Expand Down Expand Up @@ -343,6 +344,11 @@ if ($i.isSilenced && visibility.value === 'public') {
visibility.value = 'home';
}
if ($i.isSensitive && !useCw.value) {
useCw.value = true;
cw.value = i18n.ts.sensitiveUserCaution
}
if (props.channel) {
visibility.value = 'public';
localOnly.value = true; // TODO: チャンネルが連合するようになった折には消す
Expand Down
19 changes: 19 additions & 0 deletions packages/frontend/src/components/MkUserSensitiveCaution.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template>
<div :class="$style.root"><i class="ti ti-alert-triangle" style="margin-right: 8px;"></i>{{ i18n.ts.sensitiveUserCaution }}</div>
</template>

<script lang="ts" setup>
import { i18n } from '@/i18n.js';
</script>

<style lang="scss" module>
.root {
font-size: 0.8em;
padding: 16px;
background: var(--infoWarnBg);
color: var(--error);
border-radius: var(--radius);
}
</style>
3 changes: 3 additions & 0 deletions packages/frontend/src/pages/settings/profile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="_gaps_m">
<MkSwitch v-model="profile.isCat">{{ i18n.ts.flagAsCat }}<template #caption>{{ i18n.ts.flagAsCatDescription }}</template></MkSwitch>
<MkSwitch v-model="profile.isBot">{{ i18n.ts.flagAsBot }}<template #caption>{{ i18n.ts.flagAsBotDescription }}</template></MkSwitch>
<MkSwitch v-model="profile.isSensitive">{{ i18n.ts.flagAsSensitive }}<template #caption>{{ i18n.ts.flagAsSensitiveDescription }}</template></MkSwitch>
</div>
</MkFolder>

Expand Down Expand Up @@ -144,6 +145,7 @@ const profile = reactive({
lang: $i.lang,
isBot: $i.isBot ?? false,
isCat: $i.isCat ?? false,
isSensitive: $i.isSensitive ?? false,
});
watch(() => profile, () => {
Expand Down Expand Up @@ -193,6 +195,7 @@ function save() {
lang: profile.lang || null,
isBot: !!profile.isBot,
isCat: !!profile.isCat,
isSensitive: !!profile.isSensitive,
});
globalEvents.emit('requestClearPageCache');
claimAchievement('profileFilled');
Expand Down
2 changes: 2 additions & 0 deletions packages/frontend/src/pages/user/home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="profile _gaps">
<MkAccountMoved v-if="user.movedTo" :movedTo="user.movedTo"/>
<MkRemoteCaution v-if="user.host != null" :href="user.url ?? user.uri!" class="warn"/>
<MkUserSensitiveCaution v-if="user.isSensitive" />
<div :key="user.id" class="main _panel">
<div class="banner-container" :style="style">
Expand Down Expand Up @@ -174,6 +175,7 @@ import MkNote from '@/components/MkNote.vue';
import MkFollowButton from '@/components/MkFollowButton.vue';
import MkAccountMoved from '@/components/MkAccountMoved.vue';
import MkRemoteCaution from '@/components/MkRemoteCaution.vue';
import MkUserSensitiveCaution from '@/components/MkUserSensitiveCaution.vue';
import MkTextarea from '@/components/MkTextarea.vue';
import MkOmit from '@/components/MkOmit.vue';
import MkInfo from '@/components/MkInfo.vue';
Expand Down

0 comments on commit 1a6fa7e

Please sign in to comment.