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>
This commit is contained in:
Johann150 2022-01-20 19:06:38 +01:00 committed by GitHub
parent e2d2a4e2e4
commit cbb7e95d82
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 169 additions and 59 deletions

View file

@ -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"`);
}
};

View file

@ -51,6 +51,11 @@ export class AbuseUserReport {
})
public resolved: boolean;
@Column('boolean', {
default: false
})
public forwarded: boolean;
@Column('varchar', {
length: 2048,
})

View file

@ -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,
});
}

View file

@ -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,
};
};

View file

@ -46,6 +46,11 @@ export const meta = {
]),
default: 'combined',
},
forwarded: {
validator: $.optional.bool,
default: false,
},
},
res: {

View file

@ -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,
});
});