From 4c945850f4d9e09f41ea85b82a431943cf35ead3 Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Sat, 24 Dec 2022 08:03:37 +0000
Subject: [PATCH 01/10] Reports: The reporting contact id is added

---
 database.sql                                |  5 +-
 doc/database/db_report.md                   | 31 ++++++-----
 src/Moderation/Entity/Report.php            |  5 +-
 src/Moderation/Factory/Report.php           |  5 +-
 src/Moderation/Repository/Report.php        |  9 +--
 src/Module/Api/Mastodon/Reports.php         |  2 +-
 src/Protocol/ActivityPub/Processor.php      | 12 +++-
 static/dbstructure.config.php               |  4 +-
 tests/src/Moderation/Factory/ReportTest.php | 61 ++++++++++++---------
 9 files changed, 82 insertions(+), 52 deletions(-)

diff --git a/database.sql b/database.sql
index d93c979f0..2f8882d4b 100644
--- a/database.sql
+++ b/database.sql
@@ -1,6 +1,6 @@
 -- ------------------------------------------
 -- Friendica 2023.03-dev (Giant Rhubarb)
--- DB_UPDATE_VERSION 1503
+-- DB_UPDATE_VERSION 1504
 -- ------------------------------------------
 
 
@@ -1674,6 +1674,7 @@ CREATE TABLE IF NOT EXISTS `register` (
 CREATE TABLE IF NOT EXISTS `report` (
 	`id` int unsigned NOT NULL auto_increment COMMENT 'sequential ID',
 	`uid` mediumint unsigned COMMENT 'Reporting user',
+	`reporter-id` int unsigned COMMENT 'Reporting contact',
 	`cid` int unsigned NOT NULL COMMENT 'Reported contact',
 	`comment` text COMMENT 'Report',
 	`forward` boolean COMMENT 'Forward the report to the remote server',
@@ -1682,7 +1683,9 @@ CREATE TABLE IF NOT EXISTS `report` (
 	 PRIMARY KEY(`id`),
 	 INDEX `uid` (`uid`),
 	 INDEX `cid` (`cid`),
+	 INDEX `reporter-id` (`reporter-id`),
 	FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE,
+	FOREIGN KEY (`reporter-id`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
 	FOREIGN KEY (`cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
 ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='';
 
diff --git a/doc/database/db_report.md b/doc/database/db_report.md
index 9a87abe1f..fcec88234 100644
--- a/doc/database/db_report.md
+++ b/doc/database/db_report.md
@@ -6,24 +6,26 @@ Table report
 Fields
 ------
 
-| Field   | Description                             | Type               | Null | Key | Default             | Extra          |
-| ------- | --------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
-| id      | sequential ID                           | int unsigned       | NO   | PRI | NULL                | auto_increment |
-| uid     | Reporting user                          | mediumint unsigned | YES  |     | NULL                |                |
-| cid     | Reported contact                        | int unsigned       | NO   |     | NULL                |                |
-| comment | Report                                  | text               | YES  |     | NULL                |                |
-| forward | Forward the report to the remote server | boolean            | YES  |     | NULL                |                |
-| created |                                         | datetime           | NO   |     | 0001-01-01 00:00:00 |                |
-| status  | Status of the report                    | tinyint unsigned   | YES  |     | NULL                |                |
+| Field       | Description                             | Type               | Null | Key | Default             | Extra          |
+| ----------- | --------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
+| id          | sequential ID                           | int unsigned       | NO   | PRI | NULL                | auto_increment |
+| uid         | Reporting user                          | mediumint unsigned | YES  |     | NULL                |                |
+| reporter-id | Reporting contact                       | int unsigned       | YES  |     | NULL                |                |
+| cid         | Reported contact                        | int unsigned       | NO   |     | NULL                |                |
+| comment     | Report                                  | text               | YES  |     | NULL                |                |
+| forward     | Forward the report to the remote server | boolean            | YES  |     | NULL                |                |
+| created     |                                         | datetime           | NO   |     | 0001-01-01 00:00:00 |                |
+| status      | Status of the report                    | tinyint unsigned   | YES  |     | NULL                |                |
 
 Indexes
 ------------
 
-| Name    | Fields |
-| ------- | ------ |
-| PRIMARY | id     |
-| uid     | uid    |
-| cid     | cid    |
+| Name        | Fields      |
+| ----------- | ----------- |
+| PRIMARY     | id          |
+| uid         | uid         |
+| cid         | cid         |
+| reporter-id | reporter-id |
 
 Foreign Keys
 ------------
@@ -31,6 +33,7 @@ Foreign Keys
 | Field | Target Table | Target Field |
 |-------|--------------|--------------|
 | uid | [user](help/database/db_user) | uid |
+| reporter-id | [contact](help/database/db_contact) | id |
 | cid | [contact](help/database/db_contact) | id |
 
 Return to [database documentation](help/database)
diff --git a/src/Moderation/Entity/Report.php b/src/Moderation/Entity/Report.php
index 93d42b94e..957cef865 100644
--- a/src/Moderation/Entity/Report.php
+++ b/src/Moderation/Entity/Report.php
@@ -35,6 +35,8 @@ class Report extends \Friendica\BaseEntity
 	/** @var int|null */
 	protected $id;
 	/** @var int ID of the user making a moderation report*/
+	protected $reporterId;
+	/** @var int ID of the contact making a moderation report*/
 	protected $uid;
 	/** @var int ID of the contact being reported*/
 	protected $cid;
@@ -47,9 +49,10 @@ class Report extends \Friendica\BaseEntity
 	/** @var array Optional list of URI IDs of posts supporting the report*/
 	protected $postUriIds;
 
-	public function __construct(int $uid, int $cid, \DateTime $created, string $comment = '', bool $forward = false, array $postUriIds = [], int $id = null)
+	public function __construct(int $uid = null, int $reporterId, int $cid, \DateTime $created, string $comment = '', bool $forward = false, array $postUriIds = [], int $id = null)
 	{
 		$this->uid        = $uid;
+		$this->reporterId = $reporterId;
 		$this->cid        = $cid;
 		$this->created    = $created;
 		$this->comment    = $comment;
diff --git a/src/Moderation/Factory/Report.php b/src/Moderation/Factory/Report.php
index 17203d307..918c10bc8 100644
--- a/src/Moderation/Factory/Report.php
+++ b/src/Moderation/Factory/Report.php
@@ -36,6 +36,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow
 	{
 		return new Entity\Report(
 			$row['uid'],
+			$row['reporter-id'],
 			$row['cid'],
 			new \DateTime($row['created'] ?? 'now', new \DateTimeZone('UTC')),
 			$row['comment'],
@@ -51,6 +52,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow
 	 * @see \Friendica\Module\Api\Mastodon\Reports::post()
 	 *
 	 * @param int    $uid
+	 * @param int    $reporterId
 	 * @param int    $cid
 	 * @param string $comment
 	 * @param bool   $forward
@@ -58,10 +60,11 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow
 	 * @return Entity\Report
 	 * @throws \Exception
 	 */
-	public function createFromReportsRequest(int $uid, int $cid, string $comment = '', bool $forward = false, array $postUriIds = []): Entity\Report
+	public function createFromReportsRequest(int $uid = null, int $reporterId, int $cid, string $comment = '', bool $forward = false, array $postUriIds = []): Entity\Report
 	{
 		return new Entity\Report(
 			$uid,
+			$reporterId,
 			$cid,
 			new \DateTime('now', new \DateTimeZone('UTC')),
 			$comment,
diff --git a/src/Moderation/Repository/Report.php b/src/Moderation/Repository/Report.php
index 75a7f06dc..1882d8571 100644
--- a/src/Moderation/Repository/Report.php
+++ b/src/Moderation/Repository/Report.php
@@ -53,10 +53,11 @@ class Report extends \Friendica\BaseRepository
 	public function save(\Friendica\Moderation\Entity\Report $Report)
 	{
 		$fields = [
-			'uid'     => $Report->uid,
-			'cid'     => $Report->cid,
-			'comment' => $Report->comment,
-			'forward' => $Report->forward,
+			'uid'         => $Report->uid,
+			'reporter-id' => $Report->reporterId,
+			'cid'         => $Report->cid,
+			'comment'     => $Report->comment,
+			'forward'     => $Report->forward,
 		];
 
 		$postUriIds = $Report->postUriIds;
diff --git a/src/Module/Api/Mastodon/Reports.php b/src/Module/Api/Mastodon/Reports.php
index 6ae54eb6f..c8dc0044c 100644
--- a/src/Module/Api/Mastodon/Reports.php
+++ b/src/Module/Api/Mastodon/Reports.php
@@ -65,7 +65,7 @@ class Reports extends BaseApi
 			throw new HTTPException\NotFoundException('Account ' . $request['account_id'] . ' not found');
 		}
 
-		$report = $this->reportFactory->createFromReportsRequest(self::getCurrentUserID(), $request['account_id'], $request['comment'], $request['forward'], $request['status_ids']);
+		$report = $this->reportFactory->createFromReportsRequest(self::getCurrentUserID(), Contact::getPublicIdByUserId(self::getCurrentUserID()), $request['account_id'], $request['comment'], $request['forward'], $request['status_ids']);
 
 		$this->reportRepo->save($report);
 
diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php
index 843f4b8cf..76d050bd2 100644
--- a/src/Protocol/ActivityPub/Processor.php
+++ b/src/Protocol/ActivityPub/Processor.php
@@ -1837,6 +1837,13 @@ class Processor
 			return;
 		}
 
+		$reporter_id = Contact::getIdForURL($activity['actor']);
+		if (empty($account_id)) {
+			Logger::info('Unknown actor', ['activity' => $activity]);
+			Queue::remove($activity);
+			return;
+		}
+
 		$status_ids = $activity['object_ids'];
 		array_shift($status_ids);
 
@@ -1848,11 +1855,10 @@ class Processor
 			}
 		}
 
-		// @todo We should store the actor
-		$report = DI::reportFactory()->createFromReportsRequest(0, $account_id, $activity['content'], false, $uri_ids);
+		$report = DI::reportFactory()->createFromReportsRequest(null, $reporter_id, $account_id, $activity['content'], false, $uri_ids);
 		DI::report()->save($report);
 
-		Logger::info('Stored report', ['account_id' => $account_id, 'comment' => $activity['content'], 'status_ids' => $status_ids]);
+		Logger::info('Stored report', ['reporter' => $reporter_id, 'account_id' => $account_id, 'comment' => $activity['content'], 'status_ids' => $status_ids]);
 	}
 
 	/**
diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php
index ac2bb0e1e..59046a6cc 100644
--- a/static/dbstructure.config.php
+++ b/static/dbstructure.config.php
@@ -55,7 +55,7 @@
 use Friendica\Database\DBA;
 
 if (!defined('DB_UPDATE_VERSION')) {
-	define('DB_UPDATE_VERSION', 1503);
+	define('DB_UPDATE_VERSION', 1504);
 }
 
 return [
@@ -1673,6 +1673,7 @@ return [
 		"fields" => [
 			"id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
 			"uid" => ["type" => "mediumint unsigned", "foreign" => ["user" => "uid"], "comment" => "Reporting user"],
+			"reporter-id" => ["type" => "int unsigned", "foreign" => ["contact" => "id"], "comment" => "Reporting contact"],
 			"cid" => ["type" => "int unsigned", "not null" => "1", "foreign" => ["contact" => "id"], "comment" => "Reported contact"],
 			"comment" => ["type" => "text", "comment" => "Report"],
 			"forward" => ["type" => "boolean", "comment" => "Forward the report to the remote server"],
@@ -1683,6 +1684,7 @@ return [
 			"PRIMARY" => ["id"],
 			"uid" => ["uid"],
 			"cid" => ["cid"],
+			"reporter-id" => ["reporter-id"],
 		]
 	],
 	"report-post" => [
diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php
index 0f2970910..fa9461529 100644
--- a/tests/src/Moderation/Factory/ReportTest.php
+++ b/tests/src/Moderation/Factory/ReportTest.php
@@ -33,16 +33,18 @@ class ReportTest extends MockedTest
 		return [
 			'default' => [
 				'row' => [
-					'id'      => 11,
-					'uid'     => 12,
-					'cid'     => 13,
-					'comment' => '',
-					'forward' => false,
-					'created' => null
+					'id'          => 11,
+					'uid'         => 12,
+					'reporter-id' => 14,
+					'cid'         => 13,
+					'comment'     => '',
+					'forward'     => false,
+					'created'     => null
 				],
 				'postUriIds' => [],
 				'assertion'  => new Entity\Report(
 					12,
+					14,
 					13,
 					new \DateTime('now', new \DateTimeZone('UTC')),
 					'',
@@ -53,16 +55,18 @@ class ReportTest extends MockedTest
 			],
 			'full' => [
 				'row' => [
-					'id'      => 11,
-					'uid'     => 12,
-					'cid'     => 13,
-					'comment' => 'Report',
-					'forward' => true,
-					'created' => '2021-10-12 12:23:00'
+					'id'          => 11,
+					'uid'         => 12,
+					'reporter-id' => 14,
+					'cid'         => 13,
+					'comment'     => 'Report',
+					'forward'     => true,
+					'created'     => '2021-10-12 12:23:00'
 				],
 				'postUriIds' => [89, 90],
 				'assertion'  => new Entity\Report(
 					12,
+					14,
 					13,
 					new \DateTime('2021-10-12 12:23:00', new \DateTimeZone('UTC')),
 					'Report',
@@ -81,6 +85,7 @@ class ReportTest extends MockedTest
 			$report->id
 		);
 		self::assertEquals($assertion->uid, $report->uid);
+		self::assertEquals($assertion->reporterId, $report->reporterId);
 		self::assertEquals($assertion->cid, $report->cid);
 		self::assertEquals($assertion->comment, $report->comment);
 		self::assertEquals($assertion->forward, $report->forward);
@@ -103,13 +108,15 @@ class ReportTest extends MockedTest
 	{
 		return [
 			'default' => [
-				'uid'        => 12,
-				'cid'        => 13,
-				'comment'    => '',
-				'forward'    => false,
-				'postUriIds' => [],
-				'assertion'  => new Entity\Report(
+				'uid'         => 12,
+				'reporter-id' => 14,
+				'cid'         => 13,
+				'comment'     => '',
+				'forward'     => false,
+				'postUriIds'  => [],
+				'assertion'   => new Entity\Report(
 					12,
+					14,
 					13,
 					new \DateTime('now', new \DateTimeZone('UTC')),
 					'',
@@ -119,13 +126,15 @@ class ReportTest extends MockedTest
 				),
 			],
 			'full' => [
-				'uid'        => 12,
-				'cid'        => 13,
-				'comment'    => 'Report',
-				'forward'    => true,
-				'postUriIds' => [89, 90],
-				'assertion'  => new Entity\Report(
+				'uid'         => 12,
+				'reporter-id' => 14,
+				'cid'         => 13,
+				'comment'     => 'Report',
+				'forward'     => true,
+				'postUriIds'  => [89, 90],
+				'assertion'   => new Entity\Report(
 					12,
+					14,
 					13,
 					new \DateTime('now', new \DateTimeZone('UTC')),
 					'Report',
@@ -140,10 +149,10 @@ class ReportTest extends MockedTest
 	/**
 	 * @dataProvider dataCreateFromReportsRequest
 	 */
-	public function testCreateFromReportsRequest(int $uid, int $cid, string $comment, bool $forward, array $postUriIds, Entity\Report $assertion)
+	public function testCreateFromReportsRequest(int $uid, int $reporter, int $cid, string $comment, bool $forward, array $postUriIds, Entity\Report $assertion)
 	{
 		$factory = new Factory\Report(new NullLogger());
 
-		$this->assertReport($factory->createFromReportsRequest($uid, $cid, $comment, $forward, $postUriIds), $assertion);
+		$this->assertReport($factory->createFromReportsRequest($uid, $reporter, $cid, $comment, $forward, $postUriIds), $assertion);
 	}
 }

From bf4d321aa3b37916be7b57c82f668c0d8c4c808a Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Sat, 24 Dec 2022 08:09:23 +0000
Subject: [PATCH 02/10] Wrong variable

---
 src/Protocol/ActivityPub/Processor.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php
index 76d050bd2..25c09c9cb 100644
--- a/src/Protocol/ActivityPub/Processor.php
+++ b/src/Protocol/ActivityPub/Processor.php
@@ -1838,7 +1838,7 @@ class Processor
 		}
 
 		$reporter_id = Contact::getIdForURL($activity['actor']);
-		if (empty($account_id)) {
+		if (empty($reporter_id)) {
 			Logger::info('Unknown actor', ['activity' => $activity]);
 			Queue::remove($activity);
 			return;

From 8a7d08ae2860d82fe98a26f4e86626b3c7eb4d1e Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Sat, 24 Dec 2022 13:57:43 +0000
Subject: [PATCH 03/10] Category added

---
 database.sql                                |  1 +
 doc/database/db_report.md                   | 21 +++++++++++----------
 src/Moderation/Entity/Report.php            |  5 ++++-
 src/Moderation/Factory/Report.php           |  4 +++-
 src/Moderation/Repository/Report.php        |  1 +
 src/Module/Api/Mastodon/Reports.php         | 11 ++++++-----
 src/Protocol/ActivityPub/Processor.php      |  2 +-
 static/dbstructure.config.php               |  1 +
 tests/src/Moderation/Factory/ReportTest.php |  9 +++++++--
 9 files changed, 35 insertions(+), 20 deletions(-)

diff --git a/database.sql b/database.sql
index 2f8882d4b..8c24dd4eb 100644
--- a/database.sql
+++ b/database.sql
@@ -1677,6 +1677,7 @@ CREATE TABLE IF NOT EXISTS `report` (
 	`reporter-id` int unsigned COMMENT 'Reporting contact',
 	`cid` int unsigned NOT NULL COMMENT 'Reported contact',
 	`comment` text COMMENT 'Report',
+	`category` varchar(20) COMMENT 'Category of the report (spam, violation, other)',
 	`forward` boolean COMMENT 'Forward the report to the remote server',
 	`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
 	`status` tinyint unsigned COMMENT 'Status of the report',
diff --git a/doc/database/db_report.md b/doc/database/db_report.md
index fcec88234..56f51bdd4 100644
--- a/doc/database/db_report.md
+++ b/doc/database/db_report.md
@@ -6,16 +6,17 @@ Table report
 Fields
 ------
 
-| Field       | Description                             | Type               | Null | Key | Default             | Extra          |
-| ----------- | --------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
-| id          | sequential ID                           | int unsigned       | NO   | PRI | NULL                | auto_increment |
-| uid         | Reporting user                          | mediumint unsigned | YES  |     | NULL                |                |
-| reporter-id | Reporting contact                       | int unsigned       | YES  |     | NULL                |                |
-| cid         | Reported contact                        | int unsigned       | NO   |     | NULL                |                |
-| comment     | Report                                  | text               | YES  |     | NULL                |                |
-| forward     | Forward the report to the remote server | boolean            | YES  |     | NULL                |                |
-| created     |                                         | datetime           | NO   |     | 0001-01-01 00:00:00 |                |
-| status      | Status of the report                    | tinyint unsigned   | YES  |     | NULL                |                |
+| Field       | Description                                     | Type               | Null | Key | Default             | Extra          |
+| ----------- | ----------------------------------------------- | ------------------ | ---- | --- | ------------------- | -------------- |
+| id          | sequential ID                                   | int unsigned       | NO   | PRI | NULL                | auto_increment |
+| uid         | Reporting user                                  | mediumint unsigned | YES  |     | NULL                |                |
+| reporter-id | Reporting contact                               | int unsigned       | YES  |     | NULL                |                |
+| cid         | Reported contact                                | int unsigned       | NO   |     | NULL                |                |
+| comment     | Report                                          | text               | YES  |     | NULL                |                |
+| category    | Category of the report (spam, violation, other) | varchar(20)        | YES  |     | NULL                |                |
+| forward     | Forward the report to the remote server         | boolean            | YES  |     | NULL                |                |
+| created     |                                                 | datetime           | NO   |     | 0001-01-01 00:00:00 |                |
+| status      | Status of the report                            | tinyint unsigned   | YES  |     | NULL                |                |
 
 Indexes
 ------------
diff --git a/src/Moderation/Entity/Report.php b/src/Moderation/Entity/Report.php
index 957cef865..4689a11b3 100644
--- a/src/Moderation/Entity/Report.php
+++ b/src/Moderation/Entity/Report.php
@@ -42,6 +42,8 @@ class Report extends \Friendica\BaseEntity
 	protected $cid;
 	/** @var string Optional comment */
 	protected $comment;
+	/** @var string Optional category */
+	protected $category;
 	/** @var bool Whether this report should be forwarded to the remote server */
 	protected $forward;
 	/** @var \DateTime|null When the report was created */
@@ -49,13 +51,14 @@ class Report extends \Friendica\BaseEntity
 	/** @var array Optional list of URI IDs of posts supporting the report*/
 	protected $postUriIds;
 
-	public function __construct(int $uid = null, int $reporterId, int $cid, \DateTime $created, string $comment = '', bool $forward = false, array $postUriIds = [], int $id = null)
+	public function __construct(int $uid = null, int $reporterId, int $cid, \DateTime $created, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = [], int $id = null)
 	{
 		$this->uid        = $uid;
 		$this->reporterId = $reporterId;
 		$this->cid        = $cid;
 		$this->created    = $created;
 		$this->comment    = $comment;
+		$this->category   = $category;
 		$this->forward    = $forward;
 		$this->postUriIds = $postUriIds;
 		$this->id         = $id;
diff --git a/src/Moderation/Factory/Report.php b/src/Moderation/Factory/Report.php
index 918c10bc8..fbe0aa58b 100644
--- a/src/Moderation/Factory/Report.php
+++ b/src/Moderation/Factory/Report.php
@@ -40,6 +40,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow
 			$row['cid'],
 			new \DateTime($row['created'] ?? 'now', new \DateTimeZone('UTC')),
 			$row['comment'],
+			$row['category'],
 			$row['forward'],
 			$postUriIds,
 			$row['id'],
@@ -60,7 +61,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow
 	 * @return Entity\Report
 	 * @throws \Exception
 	 */
-	public function createFromReportsRequest(int $uid = null, int $reporterId, int $cid, string $comment = '', bool $forward = false, array $postUriIds = []): Entity\Report
+	public function createFromReportsRequest(int $uid = null, int $reporterId, int $cid, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = []): Entity\Report
 	{
 		return new Entity\Report(
 			$uid,
@@ -68,6 +69,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow
 			$cid,
 			new \DateTime('now', new \DateTimeZone('UTC')),
 			$comment,
+			$category,
 			$forward,
 			$postUriIds,
 		);
diff --git a/src/Moderation/Repository/Report.php b/src/Moderation/Repository/Report.php
index 1882d8571..78d889378 100644
--- a/src/Moderation/Repository/Report.php
+++ b/src/Moderation/Repository/Report.php
@@ -57,6 +57,7 @@ class Report extends \Friendica\BaseRepository
 			'reporter-id' => $Report->reporterId,
 			'cid'         => $Report->cid,
 			'comment'     => $Report->comment,
+			'category'    => $Report->category,
 			'forward'     => $Report->forward,
 		];
 
diff --git a/src/Module/Api/Mastodon/Reports.php b/src/Module/Api/Mastodon/Reports.php
index c8dc0044c..13d41eb23 100644
--- a/src/Module/Api/Mastodon/Reports.php
+++ b/src/Module/Api/Mastodon/Reports.php
@@ -54,10 +54,11 @@ class Reports extends BaseApi
 		self::checkAllowedScope(self::SCOPE_WRITE);
 
 		$request = $this->getRequest([
-			'account_id' => '',    // ID of the account to report
-			'status_ids' => [],    // Array of Statuses to attach to the report, for context
-			'comment'    => '',    // Reason for the report (default max 1000 characters)
-			'forward'    => false, // If the account is remote, should the report be forwarded to the remote admin?
+			'account_id' => '',      // ID of the account to report
+			'status_ids' => [],      // Array of Statuses to attach to the report, for context
+			'comment'    => '',      // Reason for the report (default max 1000 characters)
+			'category'   => 'other', // Specify if the report is due to spam, violation of enumerated instance rules, or some other reason.
+			'forward'    => false,   // If the account is remote, should the report be forwarded to the remote admin?
 		], $request);
 
 		$contact = Contact::getById($request['account_id'], ['id']);
@@ -65,7 +66,7 @@ class Reports extends BaseApi
 			throw new HTTPException\NotFoundException('Account ' . $request['account_id'] . ' not found');
 		}
 
-		$report = $this->reportFactory->createFromReportsRequest(self::getCurrentUserID(), Contact::getPublicIdByUserId(self::getCurrentUserID()), $request['account_id'], $request['comment'], $request['forward'], $request['status_ids']);
+		$report = $this->reportFactory->createFromReportsRequest(self::getCurrentUserID(), Contact::getPublicIdByUserId(self::getCurrentUserID()), $request['account_id'], $request['comment'], $request['category'], $request['forward'], $request['status_ids']);
 
 		$this->reportRepo->save($report);
 
diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php
index 25c09c9cb..35bbc5623 100644
--- a/src/Protocol/ActivityPub/Processor.php
+++ b/src/Protocol/ActivityPub/Processor.php
@@ -1855,7 +1855,7 @@ class Processor
 			}
 		}
 
-		$report = DI::reportFactory()->createFromReportsRequest(null, $reporter_id, $account_id, $activity['content'], false, $uri_ids);
+		$report = DI::reportFactory()->createFromReportsRequest(null, $reporter_id, $account_id, $activity['content'], null, false, $uri_ids);
 		DI::report()->save($report);
 
 		Logger::info('Stored report', ['reporter' => $reporter_id, 'account_id' => $account_id, 'comment' => $activity['content'], 'status_ids' => $status_ids]);
diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php
index 59046a6cc..897111814 100644
--- a/static/dbstructure.config.php
+++ b/static/dbstructure.config.php
@@ -1676,6 +1676,7 @@ return [
 			"reporter-id" => ["type" => "int unsigned", "foreign" => ["contact" => "id"], "comment" => "Reporting contact"],
 			"cid" => ["type" => "int unsigned", "not null" => "1", "foreign" => ["contact" => "id"], "comment" => "Reported contact"],
 			"comment" => ["type" => "text", "comment" => "Report"],
+			"category" => ["type" => "varchar(20)", "comment" => "Category of the report (spam, violation, other)"],
 			"forward" => ["type" => "boolean", "comment" => "Forward the report to the remote server"],
 			"created" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""],
 			"status" => ["type" => "tinyint unsigned", "comment" => "Status of the report"],
diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php
index fa9461529..ea4133fea 100644
--- a/tests/src/Moderation/Factory/ReportTest.php
+++ b/tests/src/Moderation/Factory/ReportTest.php
@@ -48,6 +48,7 @@ class ReportTest extends MockedTest
 					13,
 					new \DateTime('now', new \DateTimeZone('UTC')),
 					'',
+					null,
 					false,
 					[],
 					11,
@@ -70,6 +71,7 @@ class ReportTest extends MockedTest
 					13,
 					new \DateTime('2021-10-12 12:23:00', new \DateTimeZone('UTC')),
 					'Report',
+					'violation',
 					true,
 					[89, 90],
 					11
@@ -88,6 +90,7 @@ class ReportTest extends MockedTest
 		self::assertEquals($assertion->reporterId, $report->reporterId);
 		self::assertEquals($assertion->cid, $report->cid);
 		self::assertEquals($assertion->comment, $report->comment);
+		self::assertEquals($assertion->category, $report->category);
 		self::assertEquals($assertion->forward, $report->forward);
 		// No way to test "now" at the moment
 		//self::assertEquals($assertion->created, $report->created);
@@ -120,6 +123,7 @@ class ReportTest extends MockedTest
 					13,
 					new \DateTime('now', new \DateTimeZone('UTC')),
 					'',
+					null,
 					false,
 					[],
 					null
@@ -138,6 +142,7 @@ class ReportTest extends MockedTest
 					13,
 					new \DateTime('now', new \DateTimeZone('UTC')),
 					'Report',
+					'violation',
 					true,
 					[89, 90],
 					null
@@ -149,10 +154,10 @@ class ReportTest extends MockedTest
 	/**
 	 * @dataProvider dataCreateFromReportsRequest
 	 */
-	public function testCreateFromReportsRequest(int $uid, int $reporter, int $cid, string $comment, bool $forward, array $postUriIds, Entity\Report $assertion)
+	public function testCreateFromReportsRequest(int $uid, int $reporter, int $cid, string $comment, string $category = null, bool $forward, array $postUriIds, Entity\Report $assertion)
 	{
 		$factory = new Factory\Report(new NullLogger());
 
-		$this->assertReport($factory->createFromReportsRequest($uid, $reporter, $cid, $comment, $forward, $postUriIds), $assertion);
+		$this->assertReport($factory->createFromReportsRequest($uid, $reporter, $cid, $comment, $category, $forward, $postUriIds), $assertion);
 	}
 }

From 59a848c8ec0d4ab94ef7f59d2d60fd9de0619c94 Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Sat, 24 Dec 2022 23:26:54 +0000
Subject: [PATCH 04/10] Tests

---
 tests/src/Moderation/Factory/ReportTest.php | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php
index ea4133fea..5eb4cb323 100644
--- a/tests/src/Moderation/Factory/ReportTest.php
+++ b/tests/src/Moderation/Factory/ReportTest.php
@@ -38,6 +38,7 @@ class ReportTest extends MockedTest
 					'reporter-id' => 14,
 					'cid'         => 13,
 					'comment'     => '',
+					'category'    => null,
 					'forward'     => false,
 					'created'     => null
 				],
@@ -61,6 +62,7 @@ class ReportTest extends MockedTest
 					'reporter-id' => 14,
 					'cid'         => 13,
 					'comment'     => 'Report',
+					'category'    => 'violation',
 					'forward'     => true,
 					'created'     => '2021-10-12 12:23:00'
 				],
@@ -115,6 +117,7 @@ class ReportTest extends MockedTest
 				'reporter-id' => 14,
 				'cid'         => 13,
 				'comment'     => '',
+				'category'    => null,
 				'forward'     => false,
 				'postUriIds'  => [],
 				'assertion'   => new Entity\Report(
@@ -134,6 +137,7 @@ class ReportTest extends MockedTest
 				'reporter-id' => 14,
 				'cid'         => 13,
 				'comment'     => 'Report',
+				'category'    => 'violation',
 				'forward'     => true,
 				'postUriIds'  => [89, 90],
 				'assertion'   => new Entity\Report(

From dc73cbe30c1b19cbc22e2c1279a3dd53bf947860 Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Sat, 24 Dec 2022 23:33:21 +0000
Subject: [PATCH 05/10] Simplified code

---
 src/Protocol/ActivityPub/Processor.php | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php
index 35bbc5623..0390913be 100644
--- a/src/Protocol/ActivityPub/Processor.php
+++ b/src/Protocol/ActivityPub/Processor.php
@@ -1844,11 +1844,8 @@ class Processor
 			return;
 		}
 
-		$status_ids = $activity['object_ids'];
-		array_shift($status_ids);
-
 		$uri_ids = [];
-		foreach ($status_ids as $status_id) {
+		foreach ($activity['object_ids'] as $status_id) {
 			$post = Post::selectFirst(['uri-id'], ['uri' => $status_id]);
 			if (!empty($post['uri-id'])) {
 				$uri_ids[] = $post['uri-id'];
@@ -1858,7 +1855,7 @@ class Processor
 		$report = DI::reportFactory()->createFromReportsRequest(null, $reporter_id, $account_id, $activity['content'], null, false, $uri_ids);
 		DI::report()->save($report);
 
-		Logger::info('Stored report', ['reporter' => $reporter_id, 'account_id' => $account_id, 'comment' => $activity['content'], 'status_ids' => $status_ids]);
+		Logger::info('Stored report', ['reporter' => $reporter_id, 'account_id' => $account_id, 'comment' => $activity['content'], 'object_ids' => $activity['object_ids']]);
 	}
 
 	/**

From cef434942177fdef2645c0a2e99a9ac44c3b7cc0 Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Sun, 25 Dec 2022 07:30:39 +0000
Subject: [PATCH 06/10] Changed parameter order

---
 src/Moderation/Entity/Report.php            | 14 ++++++++------
 src/Moderation/Factory/Report.php           |  6 +++---
 src/Module/Api/Mastodon/Reports.php         |  2 +-
 src/Protocol/ActivityPub/Processor.php      |  2 +-
 tests/src/Moderation/Factory/ReportTest.php | 12 ++++++------
 5 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/src/Moderation/Entity/Report.php b/src/Moderation/Entity/Report.php
index 4689a11b3..2bb4350d4 100644
--- a/src/Moderation/Entity/Report.php
+++ b/src/Moderation/Entity/Report.php
@@ -23,21 +23,21 @@ namespace Friendica\Moderation\Entity;
 
 /**
  * @property-read int            $id
- * @property-read int            $uid
+ * @property-read int            $reporterId
  * @property-read int            $cid
  * @property-read string         $comment
+ * @property-read string|null    $category
  * @property-read bool           $forward
  * @property-read array          $postUriIds
+ * @property-read int            $uid
  * @property-read \DateTime|null $created
  */
 class Report extends \Friendica\BaseEntity
 {
 	/** @var int|null */
 	protected $id;
-	/** @var int ID of the user making a moderation report*/
-	protected $reporterId;
 	/** @var int ID of the contact making a moderation report*/
-	protected $uid;
+	protected $reporterId;
 	/** @var int ID of the contact being reported*/
 	protected $cid;
 	/** @var string Optional comment */
@@ -50,10 +50,11 @@ class Report extends \Friendica\BaseEntity
 	protected $created;
 	/** @var array Optional list of URI IDs of posts supporting the report*/
 	protected $postUriIds;
+	/** @var int ID of the user making a moderation report*/
+	protected $uid;
 
-	public function __construct(int $uid = null, int $reporterId, int $cid, \DateTime $created, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = [], int $id = null)
+	public function __construct(int $reporterId, int $cid, \DateTime $created, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = [], int $uid = null, int $id = null)
 	{
-		$this->uid        = $uid;
 		$this->reporterId = $reporterId;
 		$this->cid        = $cid;
 		$this->created    = $created;
@@ -61,6 +62,7 @@ class Report extends \Friendica\BaseEntity
 		$this->category   = $category;
 		$this->forward    = $forward;
 		$this->postUriIds = $postUriIds;
+		$this->uid        = $uid;
 		$this->id         = $id;
 	}
 }
diff --git a/src/Moderation/Factory/Report.php b/src/Moderation/Factory/Report.php
index fbe0aa58b..bbcbe8eb1 100644
--- a/src/Moderation/Factory/Report.php
+++ b/src/Moderation/Factory/Report.php
@@ -35,7 +35,6 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow
 	public function createFromTableRow(array $row, array $postUriIds = []): Entity\Report
 	{
 		return new Entity\Report(
-			$row['uid'],
 			$row['reporter-id'],
 			$row['cid'],
 			new \DateTime($row['created'] ?? 'now', new \DateTimeZone('UTC')),
@@ -43,6 +42,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow
 			$row['category'],
 			$row['forward'],
 			$postUriIds,
+			$row['uid'],
 			$row['id'],
 		);
 	}
@@ -61,10 +61,9 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow
 	 * @return Entity\Report
 	 * @throws \Exception
 	 */
-	public function createFromReportsRequest(int $uid = null, int $reporterId, int $cid, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = []): Entity\Report
+	public function createFromReportsRequest(int $reporterId, int $cid, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = [], int $uid = null): Entity\Report
 	{
 		return new Entity\Report(
-			$uid,
 			$reporterId,
 			$cid,
 			new \DateTime('now', new \DateTimeZone('UTC')),
@@ -72,6 +71,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow
 			$category,
 			$forward,
 			$postUriIds,
+			$uid,
 		);
 	}
 }
diff --git a/src/Module/Api/Mastodon/Reports.php b/src/Module/Api/Mastodon/Reports.php
index 13d41eb23..7d98a5e66 100644
--- a/src/Module/Api/Mastodon/Reports.php
+++ b/src/Module/Api/Mastodon/Reports.php
@@ -66,7 +66,7 @@ class Reports extends BaseApi
 			throw new HTTPException\NotFoundException('Account ' . $request['account_id'] . ' not found');
 		}
 
-		$report = $this->reportFactory->createFromReportsRequest(self::getCurrentUserID(), Contact::getPublicIdByUserId(self::getCurrentUserID()), $request['account_id'], $request['comment'], $request['category'], $request['forward'], $request['status_ids']);
+		$report = $this->reportFactory->createFromReportsRequest(Contact::getPublicIdByUserId(self::getCurrentUserID()), $request['account_id'], $request['comment'], $request['category'], $request['forward'], $request['status_ids'], self::getCurrentUserID());
 
 		$this->reportRepo->save($report);
 
diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php
index 0390913be..400a52b32 100644
--- a/src/Protocol/ActivityPub/Processor.php
+++ b/src/Protocol/ActivityPub/Processor.php
@@ -1852,7 +1852,7 @@ class Processor
 			}
 		}
 
-		$report = DI::reportFactory()->createFromReportsRequest(null, $reporter_id, $account_id, $activity['content'], null, false, $uri_ids);
+		$report = DI::reportFactory()->createFromReportsRequest($reporter_id, $account_id, $activity['content'], null, false, $uri_ids);
 		DI::report()->save($report);
 
 		Logger::info('Stored report', ['reporter' => $reporter_id, 'account_id' => $account_id, 'comment' => $activity['content'], 'object_ids' => $activity['object_ids']]);
diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php
index 5eb4cb323..f21dd2ec4 100644
--- a/tests/src/Moderation/Factory/ReportTest.php
+++ b/tests/src/Moderation/Factory/ReportTest.php
@@ -44,7 +44,6 @@ class ReportTest extends MockedTest
 				],
 				'postUriIds' => [],
 				'assertion'  => new Entity\Report(
-					12,
 					14,
 					13,
 					new \DateTime('now', new \DateTimeZone('UTC')),
@@ -52,6 +51,7 @@ class ReportTest extends MockedTest
 					null,
 					false,
 					[],
+					12,
 					11,
 				),
 			],
@@ -68,7 +68,6 @@ class ReportTest extends MockedTest
 				],
 				'postUriIds' => [89, 90],
 				'assertion'  => new Entity\Report(
-					12,
 					14,
 					13,
 					new \DateTime('2021-10-12 12:23:00', new \DateTimeZone('UTC')),
@@ -76,6 +75,7 @@ class ReportTest extends MockedTest
 					'violation',
 					true,
 					[89, 90],
+					12,
 					11
 				),
 			],
@@ -121,7 +121,6 @@ class ReportTest extends MockedTest
 				'forward'     => false,
 				'postUriIds'  => [],
 				'assertion'   => new Entity\Report(
-					12,
 					14,
 					13,
 					new \DateTime('now', new \DateTimeZone('UTC')),
@@ -129,6 +128,7 @@ class ReportTest extends MockedTest
 					null,
 					false,
 					[],
+					12,
 					null
 				),
 			],
@@ -141,7 +141,6 @@ class ReportTest extends MockedTest
 				'forward'     => true,
 				'postUriIds'  => [89, 90],
 				'assertion'   => new Entity\Report(
-					12,
 					14,
 					13,
 					new \DateTime('now', new \DateTimeZone('UTC')),
@@ -149,6 +148,7 @@ class ReportTest extends MockedTest
 					'violation',
 					true,
 					[89, 90],
+					12,
 					null
 				),
 			],
@@ -158,10 +158,10 @@ class ReportTest extends MockedTest
 	/**
 	 * @dataProvider dataCreateFromReportsRequest
 	 */
-	public function testCreateFromReportsRequest(int $uid, int $reporter, int $cid, string $comment, string $category = null, bool $forward, array $postUriIds, Entity\Report $assertion)
+	public function testCreateFromReportsRequest(int $reporter, int $cid, string $comment, string $category = null, bool $forward, array $postUriIds, int $uid, Entity\Report $assertion)
 	{
 		$factory = new Factory\Report(new NullLogger());
 
-		$this->assertReport($factory->createFromReportsRequest($uid, $reporter, $cid, $comment, $category, $forward, $postUriIds), $assertion);
+		$this->assertReport($factory->createFromReportsRequest($reporter, $cid, $comment, $category, $forward, $postUriIds, $uid), $assertion);
 	}
 }

From fd53cf824fdc138880d7300587741c29b466331a Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Sun, 25 Dec 2022 07:40:19 +0000
Subject: [PATCH 07/10] Tests

---
 tests/src/Moderation/Factory/ReportTest.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php
index f21dd2ec4..be406f499 100644
--- a/tests/src/Moderation/Factory/ReportTest.php
+++ b/tests/src/Moderation/Factory/ReportTest.php
@@ -113,13 +113,13 @@ class ReportTest extends MockedTest
 	{
 		return [
 			'default' => [
-				'uid'         => 12,
 				'reporter-id' => 14,
 				'cid'         => 13,
 				'comment'     => '',
 				'category'    => null,
 				'forward'     => false,
 				'postUriIds'  => [],
+				'uid'         => 12,
 				'assertion'   => new Entity\Report(
 					14,
 					13,
@@ -133,13 +133,13 @@ class ReportTest extends MockedTest
 				),
 			],
 			'full' => [
-				'uid'         => 12,
 				'reporter-id' => 14,
 				'cid'         => 13,
 				'comment'     => 'Report',
 				'category'    => 'violation',
 				'forward'     => true,
 				'postUriIds'  => [89, 90],
+				'uid'         => 12,
 				'assertion'   => new Entity\Report(
 					14,
 					13,

From 5298cd73b3a798fcf2cc0a1a41139839d3dbe63d Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Sun, 25 Dec 2022 10:44:06 +0000
Subject: [PATCH 08/10] We now store the violation as well

---
 database.sql                                |  1 +
 doc/database/db_report.md                   |  1 +
 src/Core/System.php                         |  9 +++++++--
 src/Moderation/Entity/Report.php            |  5 ++++-
 src/Moderation/Factory/Report.php           |  4 +++-
 src/Moderation/Repository/Report.php        |  1 +
 src/Module/Api/Mastodon/Reports.php         | 12 +++++++++++-
 src/Protocol/ActivityPub/Processor.php      |  2 +-
 static/dbstructure.config.php               |  1 +
 tests/src/Moderation/Factory/ReportTest.php | 10 ++++++++--
 10 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/database.sql b/database.sql
index 8c24dd4eb..7eb756cf2 100644
--- a/database.sql
+++ b/database.sql
@@ -1678,6 +1678,7 @@ CREATE TABLE IF NOT EXISTS `report` (
 	`cid` int unsigned NOT NULL COMMENT 'Reported contact',
 	`comment` text COMMENT 'Report',
 	`category` varchar(20) COMMENT 'Category of the report (spam, violation, other)',
+	`rules` text COMMENT 'Violated rules',
 	`forward` boolean COMMENT 'Forward the report to the remote server',
 	`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
 	`status` tinyint unsigned COMMENT 'Status of the report',
diff --git a/doc/database/db_report.md b/doc/database/db_report.md
index 56f51bdd4..92c0cced3 100644
--- a/doc/database/db_report.md
+++ b/doc/database/db_report.md
@@ -14,6 +14,7 @@ Fields
 | cid         | Reported contact                                | int unsigned       | NO   |     | NULL                |                |
 | comment     | Report                                          | text               | YES  |     | NULL                |                |
 | category    | Category of the report (spam, violation, other) | varchar(20)        | YES  |     | NULL                |                |
+| rules       | Violated rules                                  | text               | YES  |     | NULL                |                |
 | forward     | Forward the report to the remote server         | boolean            | YES  |     | NULL                |                |
 | created     |                                                 | datetime           | NO   |     | 0001-01-01 00:00:00 |                |
 | status      | Status of the report                            | tinyint unsigned   | YES  |     | NULL                |                |
diff --git a/src/Core/System.php b/src/Core/System.php
index ec214fea9..65dce1bc0 100644
--- a/src/Core/System.php
+++ b/src/Core/System.php
@@ -665,10 +665,11 @@ class System
 
 	/**
 	 * Fetch the system rules
+	 * @param bool $numeric_id If set to "true", the rules are returned with a numeric id as key.
 	 *
 	 * @return array
 	 */
-	public static function getRules(): array
+	public static function getRules(bool $numeric_id = false): array
 	{
 		$rules = [];
 		$id    = 0;
@@ -681,7 +682,11 @@ class System
 			foreach (explode("\n", trim($msg)) as $line) {
 				$line = trim($line);
 				if ($line) {
-					$rules[] = ['id' => (string)++$id, 'text' => $line];
+					if ($numeric_id) {
+						$rules[++$id] = $line;
+					} else {
+						$rules[] = ['id' => (string)++$id, 'text' => $line];
+					}
 				}
 			}
 		}
diff --git a/src/Moderation/Entity/Report.php b/src/Moderation/Entity/Report.php
index 2bb4350d4..3fbd77256 100644
--- a/src/Moderation/Entity/Report.php
+++ b/src/Moderation/Entity/Report.php
@@ -44,6 +44,8 @@ class Report extends \Friendica\BaseEntity
 	protected $comment;
 	/** @var string Optional category */
 	protected $category;
+	/** @var string Violated rules */
+	protected $rules;
 	/** @var bool Whether this report should be forwarded to the remote server */
 	protected $forward;
 	/** @var \DateTime|null When the report was created */
@@ -53,13 +55,14 @@ class Report extends \Friendica\BaseEntity
 	/** @var int ID of the user making a moderation report*/
 	protected $uid;
 
-	public function __construct(int $reporterId, int $cid, \DateTime $created, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = [], int $uid = null, int $id = null)
+	public function __construct(int $reporterId, int $cid, \DateTime $created, string $comment = '', string $category = null, string $rules = '', bool $forward = false, array $postUriIds = [], int $uid = null, int $id = null)
 	{
 		$this->reporterId = $reporterId;
 		$this->cid        = $cid;
 		$this->created    = $created;
 		$this->comment    = $comment;
 		$this->category   = $category;
+		$this->rules      = $rules;
 		$this->forward    = $forward;
 		$this->postUriIds = $postUriIds;
 		$this->uid        = $uid;
diff --git a/src/Moderation/Factory/Report.php b/src/Moderation/Factory/Report.php
index bbcbe8eb1..8e66d8ad5 100644
--- a/src/Moderation/Factory/Report.php
+++ b/src/Moderation/Factory/Report.php
@@ -40,6 +40,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow
 			new \DateTime($row['created'] ?? 'now', new \DateTimeZone('UTC')),
 			$row['comment'],
 			$row['category'],
+			$row['rules'],
 			$row['forward'],
 			$postUriIds,
 			$row['uid'],
@@ -61,7 +62,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow
 	 * @return Entity\Report
 	 * @throws \Exception
 	 */
-	public function createFromReportsRequest(int $reporterId, int $cid, string $comment = '', string $category = null, bool $forward = false, array $postUriIds = [], int $uid = null): Entity\Report
+	public function createFromReportsRequest(int $reporterId, int $cid, string $comment = '', string $category = null, string $rules = '', bool $forward = false, array $postUriIds = [], int $uid = null): Entity\Report
 	{
 		return new Entity\Report(
 			$reporterId,
@@ -69,6 +70,7 @@ class Report extends \Friendica\BaseFactory implements ICanCreateFromTableRow
 			new \DateTime('now', new \DateTimeZone('UTC')),
 			$comment,
 			$category,
+			$rules,
 			$forward,
 			$postUriIds,
 			$uid,
diff --git a/src/Moderation/Repository/Report.php b/src/Moderation/Repository/Report.php
index 78d889378..5322a4ffb 100644
--- a/src/Moderation/Repository/Report.php
+++ b/src/Moderation/Repository/Report.php
@@ -58,6 +58,7 @@ class Report extends \Friendica\BaseRepository
 			'cid'         => $Report->cid,
 			'comment'     => $Report->comment,
 			'category'    => $Report->category,
+			'rules'       => $Report->rules,
 			'forward'     => $Report->forward,
 		];
 
diff --git a/src/Module/Api/Mastodon/Reports.php b/src/Module/Api/Mastodon/Reports.php
index 7d98a5e66..98213f9be 100644
--- a/src/Module/Api/Mastodon/Reports.php
+++ b/src/Module/Api/Mastodon/Reports.php
@@ -58,6 +58,7 @@ class Reports extends BaseApi
 			'status_ids' => [],      // Array of Statuses to attach to the report, for context
 			'comment'    => '',      // Reason for the report (default max 1000 characters)
 			'category'   => 'other', // Specify if the report is due to spam, violation of enumerated instance rules, or some other reason.
+			'rule_ids'   => [],      // For violation category reports, specify the ID of the exact rules broken.
 			'forward'    => false,   // If the account is remote, should the report be forwarded to the remote admin?
 		], $request);
 
@@ -66,7 +67,16 @@ class Reports extends BaseApi
 			throw new HTTPException\NotFoundException('Account ' . $request['account_id'] . ' not found');
 		}
 
-		$report = $this->reportFactory->createFromReportsRequest(Contact::getPublicIdByUserId(self::getCurrentUserID()), $request['account_id'], $request['comment'], $request['category'], $request['forward'], $request['status_ids'], self::getCurrentUserID());
+		$violation = '';
+		$rules     = System::getRules(true);
+
+		foreach ($request['rule_ids'] as $key) {
+			if (!empty($rules[$key])) {
+				$violation .= $rules[$key] . "\n";
+			}
+		}
+
+		$report = $this->reportFactory->createFromReportsRequest(Contact::getPublicIdByUserId(self::getCurrentUserID()), $request['account_id'], $request['comment'], $request['category'], trim($violation), $request['forward'], $request['status_ids'], self::getCurrentUserID());
 
 		$this->reportRepo->save($report);
 
diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php
index 400a52b32..e98fa4596 100644
--- a/src/Protocol/ActivityPub/Processor.php
+++ b/src/Protocol/ActivityPub/Processor.php
@@ -1852,7 +1852,7 @@ class Processor
 			}
 		}
 
-		$report = DI::reportFactory()->createFromReportsRequest($reporter_id, $account_id, $activity['content'], null, false, $uri_ids);
+		$report = DI::reportFactory()->createFromReportsRequest($reporter_id, $account_id, $activity['content'], null, '', false, $uri_ids);
 		DI::report()->save($report);
 
 		Logger::info('Stored report', ['reporter' => $reporter_id, 'account_id' => $account_id, 'comment' => $activity['content'], 'object_ids' => $activity['object_ids']]);
diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php
index 897111814..1d573fa87 100644
--- a/static/dbstructure.config.php
+++ b/static/dbstructure.config.php
@@ -1677,6 +1677,7 @@ return [
 			"cid" => ["type" => "int unsigned", "not null" => "1", "foreign" => ["contact" => "id"], "comment" => "Reported contact"],
 			"comment" => ["type" => "text", "comment" => "Report"],
 			"category" => ["type" => "varchar(20)", "comment" => "Category of the report (spam, violation, other)"],
+			"rules" => ["type" => "text", "comment" => "Violated rules"],
 			"forward" => ["type" => "boolean", "comment" => "Forward the report to the remote server"],
 			"created" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""],
 			"status" => ["type" => "tinyint unsigned", "comment" => "Status of the report"],
diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php
index be406f499..8d1e8131e 100644
--- a/tests/src/Moderation/Factory/ReportTest.php
+++ b/tests/src/Moderation/Factory/ReportTest.php
@@ -49,6 +49,7 @@ class ReportTest extends MockedTest
 					new \DateTime('now', new \DateTimeZone('UTC')),
 					'',
 					null,
+					'',
 					false,
 					[],
 					12,
@@ -63,6 +64,7 @@ class ReportTest extends MockedTest
 					'cid'         => 13,
 					'comment'     => 'Report',
 					'category'    => 'violation',
+					'rules'       => 'Rules',
 					'forward'     => true,
 					'created'     => '2021-10-12 12:23:00'
 				],
@@ -73,6 +75,7 @@ class ReportTest extends MockedTest
 					new \DateTime('2021-10-12 12:23:00', new \DateTimeZone('UTC')),
 					'Report',
 					'violation',
+					'Rules',
 					true,
 					[89, 90],
 					12,
@@ -117,6 +120,7 @@ class ReportTest extends MockedTest
 				'cid'         => 13,
 				'comment'     => '',
 				'category'    => null,
+				'rules'       => null,
 				'forward'     => false,
 				'postUriIds'  => [],
 				'uid'         => 12,
@@ -126,6 +130,7 @@ class ReportTest extends MockedTest
 					new \DateTime('now', new \DateTimeZone('UTC')),
 					'',
 					null,
+					'',
 					false,
 					[],
 					12,
@@ -146,6 +151,7 @@ class ReportTest extends MockedTest
 					new \DateTime('now', new \DateTimeZone('UTC')),
 					'Report',
 					'violation',
+					'Rules',
 					true,
 					[89, 90],
 					12,
@@ -158,10 +164,10 @@ class ReportTest extends MockedTest
 	/**
 	 * @dataProvider dataCreateFromReportsRequest
 	 */
-	public function testCreateFromReportsRequest(int $reporter, int $cid, string $comment, string $category = null, bool $forward, array $postUriIds, int $uid, Entity\Report $assertion)
+	public function testCreateFromReportsRequest(int $reporter, int $cid, string $comment, string $category = null, string $rules = null, bool $forward, array $postUriIds, int $uid, Entity\Report $assertion)
 	{
 		$factory = new Factory\Report(new NullLogger());
 
-		$this->assertReport($factory->createFromReportsRequest($reporter, $cid, $comment, $category, $forward, $postUriIds, $uid), $assertion);
+		$this->assertReport($factory->createFromReportsRequest($reporter, $cid, $comment, $category, $rules, $forward, $postUriIds, $uid), $assertion);
 	}
 }

From c0c70427f35f877c092aa3e41430b5381eae3282 Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Sun, 25 Dec 2022 10:52:47 +0000
Subject: [PATCH 09/10] Tests

---
 tests/src/Moderation/Factory/ReportTest.php | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php
index 8d1e8131e..7ce6ab0f0 100644
--- a/tests/src/Moderation/Factory/ReportTest.php
+++ b/tests/src/Moderation/Factory/ReportTest.php
@@ -39,6 +39,7 @@ class ReportTest extends MockedTest
 					'cid'         => 13,
 					'comment'     => '',
 					'category'    => null,
+					'rules'       => '',
 					'forward'     => false,
 					'created'     => null
 				],
@@ -96,6 +97,7 @@ class ReportTest extends MockedTest
 		self::assertEquals($assertion->cid, $report->cid);
 		self::assertEquals($assertion->comment, $report->comment);
 		self::assertEquals($assertion->category, $report->category);
+		self::assertEquals($assertion->rules, $report->rules);
 		self::assertEquals($assertion->forward, $report->forward);
 		// No way to test "now" at the moment
 		//self::assertEquals($assertion->created, $report->created);
@@ -142,6 +144,7 @@ class ReportTest extends MockedTest
 				'cid'         => 13,
 				'comment'     => 'Report',
 				'category'    => 'violation',
+				'rules'       => 'Rules',
 				'forward'     => true,
 				'postUriIds'  => [89, 90],
 				'uid'         => 12,
@@ -164,7 +167,7 @@ class ReportTest extends MockedTest
 	/**
 	 * @dataProvider dataCreateFromReportsRequest
 	 */
-	public function testCreateFromReportsRequest(int $reporter, int $cid, string $comment, string $category = null, string $rules = null, bool $forward, array $postUriIds, int $uid, Entity\Report $assertion)
+	public function testCreateFromReportsRequest(int $reporter, int $cid, string $comment, string $category = null, string $rules = '', bool $forward, array $postUriIds, int $uid, Entity\Report $assertion)
 	{
 		$factory = new Factory\Report(new NullLogger());
 

From 80247bd1ca407003510ca05e80a472ae47bceb35 Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Sun, 25 Dec 2022 10:57:27 +0000
Subject: [PATCH 10/10] Fix tests

---
 tests/src/Moderation/Factory/ReportTest.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/src/Moderation/Factory/ReportTest.php b/tests/src/Moderation/Factory/ReportTest.php
index 7ce6ab0f0..286b52992 100644
--- a/tests/src/Moderation/Factory/ReportTest.php
+++ b/tests/src/Moderation/Factory/ReportTest.php
@@ -122,7 +122,7 @@ class ReportTest extends MockedTest
 				'cid'         => 13,
 				'comment'     => '',
 				'category'    => null,
-				'rules'       => null,
+				'rules'       => '',
 				'forward'     => false,
 				'postUriIds'  => [],
 				'uid'         => 12,