summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohann150 <johann.galle@protonmail.com>2022-01-20 19:06:38 +0100
committerGitHub <noreply@github.com>2022-01-21 03:06:38 +0900
commitcbb7e95d82d363d96462b90943bf329469ad08df (patch)
tree7515ea3c4ab8e9315265a86245af74f126701563
parentfix: code url in documentation (#8117) (diff)
downloadmisskey-cbb7e95d82d363d96462b90943bf329469ad08df.tar.gz
misskey-cbb7e95d82d363d96462b90943bf329469ad08df.tar.bz2
misskey-cbb7e95d82d363d96462b90943bf329469ad08df.zip
enhance: Forward report (#8001)
* implement sending AP Flag object Optionally allow a user to select to forward a report about a remote user to the other instance. This is added in a backwards-compatible way. * add locale string * forward report only for moderators * add switch to moderator UI to forward report * fix report note url * return forwarded status from API apparently forgot to carry this over from my testing environment * object in Flag activity has to be an array For correct interoperability with Pleroma the "object" property of the Flag activity has to be an array. This array will in the future also hold the link to respective notes, so it makes sense to correct this on our side. * Update get-note-menu.ts Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
-rw-r--r--locales/ja-JP.yml3
-rw-r--r--packages/backend/migration/1637320813000-forwarded-report.js13
-rw-r--r--packages/backend/src/models/entities/abuse-user-report.ts5
-rw-r--r--packages/backend/src/models/repositories/abuse-user-report.ts1
-rw-r--r--packages/backend/src/remote/activitypub/renderer/flag.ts15
-rw-r--r--packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts5
-rw-r--r--packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts20
-rw-r--r--packages/client/src/components/abuse-report.vue102
-rw-r--r--packages/client/src/pages/admin/abuses.vue62
-rw-r--r--packages/client/src/scripts/get-note-menu.ts2
10 files changed, 169 insertions, 59 deletions
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index dd853aa83a..59ce5ee84f 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -619,8 +619,11 @@ reportAbuse: "通報"
reportAbuseOf: "{name}を通報する"
fillAbuseReportDescription: "通報理由の詳細を記入してください。対象のノートがある場合はそのURLも記入してください。"
abuseReported: "内容が送信されました。ご報告ありがとうございました。"
+reporter: "通報者"
reporteeOrigin: "通報先"
reporterOrigin: "通報元"
+forwardReport: "リモートインスタンスに通報を転送する"
+forwardReportIsAnonymous: "リモートインスタンスからはあなたの情報は見れず、匿名のシステムアカウントとして表示されます。"
send: "送信"
abuseMarkAsResolved: "対応済みにする"
openInNewTab: "新しいタブで開く"
diff --git a/packages/backend/migration/1637320813000-forwarded-report.js b/packages/backend/migration/1637320813000-forwarded-report.js
new file mode 100644
index 0000000000..4056f7b5f4
--- /dev/null
+++ b/packages/backend/migration/1637320813000-forwarded-report.js
@@ -0,0 +1,13 @@
+const { QueryRunner } = require('typeorm');
+
+module.exports = class forwardedReport1637320813000 {
+ name = 'forwardedReport1637320813000';
+
+ async up(queryRunner) {
+ await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD "forwarded" boolean NOT NULL DEFAULT false`);
+ }
+
+ async down(queryRunner) {
+ await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP COLUMN "forwarded"`);
+ }
+};
diff --git a/packages/backend/src/models/entities/abuse-user-report.ts b/packages/backend/src/models/entities/abuse-user-report.ts
index 019d613f76..27c1e47fd8 100644
--- a/packages/backend/src/models/entities/abuse-user-report.ts
+++ b/packages/backend/src/models/entities/abuse-user-report.ts
@@ -51,6 +51,11 @@ export class AbuseUserReport {
})
public resolved: boolean;
+ @Column('boolean', {
+ default: false
+ })
+ public forwarded: boolean;
+
@Column('varchar', {
length: 2048,
})
diff --git a/packages/backend/src/models/repositories/abuse-user-report.ts b/packages/backend/src/models/repositories/abuse-user-report.ts
index 5e267b3c2b..943b65eb64 100644
--- a/packages/backend/src/models/repositories/abuse-user-report.ts
+++ b/packages/backend/src/models/repositories/abuse-user-report.ts
@@ -27,6 +27,7 @@ export class AbuseUserReportRepository extends Repository<AbuseUserReport> {
assignee: report.assigneeId ? Users.pack(report.assignee || report.assigneeId, null, {
detail: true,
}) : null,
+ forwarded: report.forwarded,
});
}
diff --git a/packages/backend/src/remote/activitypub/renderer/flag.ts b/packages/backend/src/remote/activitypub/renderer/flag.ts
new file mode 100644
index 0000000000..60ac496509
--- /dev/null
+++ b/packages/backend/src/remote/activitypub/renderer/flag.ts
@@ -0,0 +1,15 @@
+import config from '@/config/index';
+import { IObject, IActivity } from '@/remote/activitypub/type';
+import { ILocalUser, IRemoteUser } from '@/models/entities/user';
+import { getInstanceActor } from '@/services/instance-actor';
+
+// to anonymise reporters, the reporting actor must be a system user
+// object has to be a uri or array of uris
+export const renderFlag = (user: ILocalUser, object: [string], content: string): IActivity => {
+ return {
+ type: 'Flag',
+ actor: `${config.url}/users/${user.id}`,
+ content,
+ object,
+ };
+};
diff --git a/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts b/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts
index 807afd2690..ed7b146d03 100644
--- a/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts
+++ b/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts
@@ -46,6 +46,11 @@ export const meta = {
]),
default: 'combined',
},
+
+ forwarded: {
+ validator: $.optional.bool,
+ default: false,
+ },
},
res: {
diff --git a/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts b/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts
index 3b47d7d35e..b00457f092 100644
--- a/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts
+++ b/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts
@@ -1,7 +1,11 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../define';
-import { AbuseUserReports } from '@/models/index';
+import { AbuseUserReports, Users } from '@/models/index';
+import { getInstanceActor } from '@/services/instance-actor';
+import { deliver } from '@/queue/index';
+import { renderActivity } from '@/remote/activitypub/renderer/index';
+import { renderFlag } from '@/remote/activitypub/renderer/flag';
export const meta = {
tags: ['admin'],
@@ -13,6 +17,12 @@ export const meta = {
reportId: {
validator: $.type(ID),
},
+
+ forward: {
+ validator: $.optional.boolean,
+ required: false,
+ default: false,
+ },
},
} as const;
@@ -24,8 +34,16 @@ export default define(meta, async (ps, me) => {
throw new Error('report not found');
}
+ if (ps.forward && report.targetUserHost != null) {
+ const actor = await getInstanceActor();
+ const targetUser = await Users.findOne(report.targetUserId);
+
+ deliver(actor, renderActivity(renderFlag(actor, [targetUser.uri], report.comment)), targetUser.inbox);
+ }
+
await AbuseUserReports.update(report.id, {
resolved: true,
assigneeId: me.id,
+ forwarded: ps.forward && report.targetUserHost != null,
});
});
diff --git a/packages/client/src/components/abuse-report.vue b/packages/client/src/components/abuse-report.vue
new file mode 100644
index 0000000000..b67cef209b
--- /dev/null
+++ b/packages/client/src/components/abuse-report.vue
@@ -0,0 +1,102 @@
+<template>
+<div class="bcekxzvu _card _gap">
+ <div class="_content target">
+ <MkAvatar class="avatar" :user="report.targetUser" :show-indicator="true"/>
+ <MkA class="info" :to="userPage(report.targetUser)" v-user-preview="report.targetUserId">
+ <MkUserName class="name" :user="report.targetUser"/>
+ <MkAcct class="acct" :user="report.targetUser" style="display: block;"/>
+ </MkA>
+ </div>
+ <div class="_content">
+ <div>
+ <Mfm :text="report.comment"/>
+ </div>
+ <hr/>
+ <div>{{ $ts.reporter }}: <MkAcct :user="report.reporter"/></div>
+ <div v-if="report.assignee">
+ {{ $ts.moderator }}:
+ <MkAcct :user="report.assignee"/>
+ </div>
+ <div><MkTime :time="report.createdAt"/></div>
+ </div>
+ <div class="_footer">
+ <MkSwitch v-model="forward" :disabled="report.targetUser.host == null || report.resolved">
+ {{ $ts.forwardReport }}
+ <template #caption>{{ $ts.forwardReportIsAnonymous }}</template>
+ </MkSwitch>
+ <MkButton v-if="!report.resolved" primary @click="resolve">{{ $ts.abuseMarkAsResolved }}</MkButton>
+ </div>
+</div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+
+import MkButton from '@/components/ui/button.vue';
+import MkSwitch from '@/components/form/switch.vue';
+import { acct, userPage } from '@/filters/user';
+import * as os from '@/os';
+
+export default defineComponent({
+ components: {
+ MkButton,
+ MkSwitch,
+ },
+
+ emits: ['resolved'],
+
+ props: {
+ report: {
+ type: Object,
+ required: true,
+ }
+ }
+
+ data() {
+ return {
+ forward: this.report.forwarded,
+ };
+ }
+
+ methods: {
+ acct,
+ userPage,
+
+ resolve() {
+ os.apiWithDialog('admin/resolve-abuse-user-report', {
+ forward: this.forward,
+ reportId: this.report.id,
+ }).then(() => {
+ this.$emit('resolved', this.report.id);
+ });
+ }
+ }
+});
+</script>
+
+<style lang="scss" scoped>
+.bcekxzvu {
+ > .target {
+ display: flex;
+ width: 100%;
+ box-sizing: border-box;
+ text-align: left;
+ align-items: center;
+
+ > .avatar {
+ width: 42px;
+ height: 42px;
+ }
+
+ > .info {
+ margin-left: 0.3em;
+ padding: 0 8px;
+ flex: 1;
+
+ > .name {
+ font-weight: bold;
+ }
+ }
+ }
+}
+</style>
diff --git a/packages/client/src/pages/admin/abuses.vue b/packages/client/src/pages/admin/abuses.vue
index 31cdef492a..92f93797ce 100644
--- a/packages/client/src/pages/admin/abuses.vue
+++ b/packages/client/src/pages/admin/abuses.vue
@@ -34,27 +34,7 @@
-->
<MkPagination v-slot="{items}" ref="reports" :pagination="pagination" style="margin-top: var(--margin);">
- <div v-for="report in items" :key="report.id" class="bcekxzvu _card _gap">
- <div class="_content target">
- <MkAvatar class="avatar" :user="report.targetUser" :show-indicator="true"/>
- <div class="info">
- <MkUserName class="name" :user="report.targetUser"/>
- <div class="acct">@{{ acct(report.targetUser) }}</div>
- </div>
- </div>
- <div class="_content">
- <div>
- <Mfm :text="report.comment"/>
- </div>
- <hr>
- <div>Reporter: <MkAcct :user="report.reporter"/></div>
- <div><MkTime :time="report.createdAt"/></div>
- </div>
- <div class="_footer">
- <div v-if="report.assignee">Assignee: <MkAcct :user="report.assignee"/></div>
- <MkButton v-if="!report.resolved" primary @click="resolve(report)">{{ $ts.abuseMarkAsResolved }}</MkButton>
- </div>
- </div>
+ <XAbuseReport v-for="report in items" :key="report.id" :report="report" @resolved="resolved"/>
</MkPagination>
</div>
</div>
@@ -64,20 +44,19 @@
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import MkButton from '@/components/ui/button.vue';
import MkInput from '@/components/form/input.vue';
import MkSelect from '@/components/form/select.vue';
import MkPagination from '@/components/ui/pagination.vue';
-import { acct } from '@/filters/user';
+import XAbuseReport from '@/components/abuse-report.vue';
import * as os from '@/os';
import * as symbols from '@/symbols';
export default defineComponent({
components: {
- MkButton,
MkInput,
MkSelect,
MkPagination,
+ XAbuseReport,
},
emits: ['info'],
@@ -107,14 +86,8 @@ export default defineComponent({
},
methods: {
- acct,
-
- resolve(report) {
- os.apiWithDialog('admin/resolve-abuse-user-report', {
- reportId: report.id,
- }).then(() => {
- this.$refs.reports.removeItem(item => item.id === report.id);
- });
+ resolved(reportId) {
+ this.$refs.reports.removeItem(item => item.id === reportId);
},
}
});
@@ -124,29 +97,4 @@ export default defineComponent({
.lcixvhis {
margin: var(--margin);
}
-
-.bcekxzvu {
- > .target {
- display: flex;
- width: 100%;
- box-sizing: border-box;
- text-align: left;
- align-items: center;
-
- > .avatar {
- width: 42px;
- height: 42px;
- }
-
- > .info {
- margin-left: 0.3em;
- padding: 0 8px;
- flex: 1;
-
- > .name {
- font-weight: bold;
- }
- }
- }
-}
</style>
diff --git a/packages/client/src/scripts/get-note-menu.ts b/packages/client/src/scripts/get-note-menu.ts
index 61120d53ba..3634f39632 100644
--- a/packages/client/src/scripts/get-note-menu.ts
+++ b/packages/client/src/scripts/get-note-menu.ts
@@ -252,7 +252,7 @@ export function getNoteMenu(props: {
icon: 'fas fa-exclamation-circle',
text: i18n.locale.reportAbuse,
action: () => {
- const u = `${url}/notes/${appearNote.id}`;
+ const u = appearNote.url || appearNote.uri || `${url}/notes/${appearNote.id}`;
os.popup(import('@/components/abuse-report-window.vue'), {
user: appearNote.user,
initialComment: `Note: ${u}\n-----\n`