✨ Abuse report
This commit is contained in:
parent
c6cb2a0dc3
commit
21cf212d8f
30
DysonNetwork.Sphere/Account/AbuseReport.cs
Normal file
30
DysonNetwork.Sphere/Account/AbuseReport.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using NodaTime;
|
||||||
|
|
||||||
|
namespace DysonNetwork.Sphere.Account;
|
||||||
|
|
||||||
|
public enum AbuseReportType
|
||||||
|
{
|
||||||
|
Copyright,
|
||||||
|
Harassment,
|
||||||
|
Impersonation,
|
||||||
|
OffensiveContent,
|
||||||
|
Spam,
|
||||||
|
PrivacyViolation,
|
||||||
|
IllegalContent,
|
||||||
|
Other
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AbuseReport : ModelBase
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; } = Guid.NewGuid();
|
||||||
|
[MaxLength(4096)] public string ResourceIdentifier { get; set; } = null!;
|
||||||
|
public AbuseReportType Type { get; set; }
|
||||||
|
[MaxLength(8192)] public string Reason { get; set; } = null!;
|
||||||
|
|
||||||
|
public Instant? ResolvedAt { get; set; }
|
||||||
|
[MaxLength(8192)] public string? Resolution { get; set; }
|
||||||
|
|
||||||
|
public Guid AccountId { get; set; }
|
||||||
|
public Account Account { get; set; } = null!;
|
||||||
|
}
|
@ -54,6 +54,7 @@ public class AppDatabase(
|
|||||||
public DbSet<NotificationPushSubscription> NotificationPushSubscriptions { get; set; }
|
public DbSet<NotificationPushSubscription> NotificationPushSubscriptions { get; set; }
|
||||||
public DbSet<Badge> Badges { get; set; }
|
public DbSet<Badge> Badges { get; set; }
|
||||||
public DbSet<ActionLog> ActionLogs { get; set; }
|
public DbSet<ActionLog> ActionLogs { get; set; }
|
||||||
|
public DbSet<AbuseReport> AbuseReports { get; set; }
|
||||||
|
|
||||||
public DbSet<Session> AuthSessions { get; set; }
|
public DbSet<Session> AuthSessions { get; set; }
|
||||||
public DbSet<Challenge> AuthChallenges { get; set; }
|
public DbSet<Challenge> AuthChallenges { get; set; }
|
||||||
|
@ -2269,7 +2269,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -852,7 +852,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
description = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: true),
|
description = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: true),
|
||||||
file_meta = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: true),
|
file_meta = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: true),
|
||||||
user_meta = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: true),
|
user_meta = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: true),
|
||||||
sensitive_marks = table.Column<List<CloudFileSensitiveMark>>(type: "jsonb", nullable: true),
|
sensitive_marks = table.Column<List<ContentSensitiveMark>>(type: "jsonb", nullable: true),
|
||||||
mime_type = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
mime_type = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||||
hash = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
hash = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||||
size = table.Column<long>(type: "bigint", nullable: false),
|
size = table.Column<long>(type: "bigint", nullable: false),
|
||||||
|
@ -2287,7 +2287,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2292,7 +2292,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2262,7 +2262,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2266,7 +2266,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2266,7 +2266,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2268,7 +2268,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2268,7 +2268,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2274,7 +2274,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2274,7 +2274,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2290,7 +2290,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2294,7 +2294,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2236,7 +2236,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2249,7 +2249,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2260,7 +2260,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2279,7 +2279,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2337,7 +2337,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2341,7 +2341,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2341,7 +2341,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
@ -2338,7 +2338,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
|
3696
DysonNetwork.Sphere/Migrations/20250625150644_SafetyAbuseReport.Designer.cs
generated
Normal file
3696
DysonNetwork.Sphere/Migrations/20250625150644_SafetyAbuseReport.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using DysonNetwork.Sphere.Storage;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using NodaTime;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace DysonNetwork.Sphere.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class SafetyAbuseReport : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<List<ContentSensitiveMark>>(
|
||||||
|
name: "sensitive_marks",
|
||||||
|
table: "posts",
|
||||||
|
type: "jsonb",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "abuse_reports",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
resource_identifier = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: false),
|
||||||
|
type = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
reason = table.Column<string>(type: "character varying(8192)", maxLength: 8192, nullable: false),
|
||||||
|
resolved_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||||
|
resolution = table.Column<string>(type: "character varying(8192)", maxLength: 8192, nullable: true),
|
||||||
|
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||||
|
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||||
|
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_abuse_reports", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_abuse_reports_accounts_account_id",
|
||||||
|
column: x => x.account_id,
|
||||||
|
principalTable: "accounts",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_abuse_reports_account_id",
|
||||||
|
table: "abuse_reports",
|
||||||
|
column: "account_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "abuse_reports");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "sensitive_marks",
|
||||||
|
table: "posts");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -32,6 +32,63 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis");
|
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis");
|
||||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("DysonNetwork.Sphere.Account.AbuseReport", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
b.Property<Guid>("AccountId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("account_id");
|
||||||
|
|
||||||
|
b.Property<Instant>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("created_at");
|
||||||
|
|
||||||
|
b.Property<Instant?>("DeletedAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("deleted_at");
|
||||||
|
|
||||||
|
b.Property<string>("Reason")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(8192)
|
||||||
|
.HasColumnType("character varying(8192)")
|
||||||
|
.HasColumnName("reason");
|
||||||
|
|
||||||
|
b.Property<string>("Resolution")
|
||||||
|
.HasMaxLength(8192)
|
||||||
|
.HasColumnType("character varying(8192)")
|
||||||
|
.HasColumnName("resolution");
|
||||||
|
|
||||||
|
b.Property<Instant?>("ResolvedAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("resolved_at");
|
||||||
|
|
||||||
|
b.Property<string>("ResourceIdentifier")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(4096)
|
||||||
|
.HasColumnType("character varying(4096)")
|
||||||
|
.HasColumnName("resource_identifier");
|
||||||
|
|
||||||
|
b.Property<int>("Type")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("type");
|
||||||
|
|
||||||
|
b.Property<Instant>("UpdatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("updated_at");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_abuse_reports");
|
||||||
|
|
||||||
|
b.HasIndex("AccountId")
|
||||||
|
.HasDatabaseName("ix_abuse_reports_account_id");
|
||||||
|
|
||||||
|
b.ToTable("abuse_reports", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Sphere.Account.Account", b =>
|
modelBuilder.Entity("DysonNetwork.Sphere.Account.Account", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
@ -1612,6 +1669,10 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasAnnotation("Npgsql:TsVectorConfig", "simple")
|
.HasAnnotation("Npgsql:TsVectorConfig", "simple")
|
||||||
.HasAnnotation("Npgsql:TsVectorProperties", new[] { "Title", "Description", "Content" });
|
.HasAnnotation("Npgsql:TsVectorProperties", new[] { "Title", "Description", "Content" });
|
||||||
|
|
||||||
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
|
.HasColumnType("jsonb")
|
||||||
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.HasMaxLength(1024)
|
.HasMaxLength(1024)
|
||||||
.HasColumnType("character varying(1024)")
|
.HasColumnType("character varying(1024)")
|
||||||
@ -2335,7 +2396,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
|
|
||||||
b.Property<List<CloudFileSensitiveMark>>("SensitiveMarks")
|
b.Property<List<ContentSensitiveMark>>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
|
|
||||||
@ -2844,6 +2905,18 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
b.ToTable("post_tag_links", (string)null);
|
b.ToTable("post_tag_links", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DysonNetwork.Sphere.Account.AbuseReport", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AccountId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_abuse_reports_accounts_account_id");
|
||||||
|
|
||||||
|
b.Navigation("Account");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Sphere.Account.AccountAuthFactor", b =>
|
modelBuilder.Entity("DysonNetwork.Sphere.Account.AccountAuthFactor", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
|
b.HasOne("DysonNetwork.Sphere.Account.Account", "Account")
|
||||||
|
@ -38,6 +38,7 @@ public class Post : ModelBase, IIdentifiedResource, IActivity
|
|||||||
|
|
||||||
public PostType Type { get; set; }
|
public PostType Type { get; set; }
|
||||||
[Column(TypeName = "jsonb")] public Dictionary<string, object>? Meta { get; set; }
|
[Column(TypeName = "jsonb")] public Dictionary<string, object>? Meta { get; set; }
|
||||||
|
[Column(TypeName = "jsonb")] public List<ContentSensitiveMark>? SensitiveMarks { get; set; } = [];
|
||||||
|
|
||||||
public int ViewsUnique { get; set; }
|
public int ViewsUnique { get; set; }
|
||||||
public int ViewsTotal { get; set; }
|
public int ViewsTotal { get; set; }
|
||||||
|
153
DysonNetwork.Sphere/Safety/AbuseReportController.cs
Normal file
153
DysonNetwork.Sphere/Safety/AbuseReportController.cs
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using DysonNetwork.Sphere.Account;
|
||||||
|
using DysonNetwork.Sphere.Permission;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace DysonNetwork.Sphere.Safety;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("/safety/reports")]
|
||||||
|
public class AbuseReportController(
|
||||||
|
SafetyService safety
|
||||||
|
) : ControllerBase
|
||||||
|
{
|
||||||
|
public class CreateReportRequest
|
||||||
|
{
|
||||||
|
[Required] public string ResourceIdentifier { get; set; } = null!;
|
||||||
|
|
||||||
|
[Required] public AbuseReportType Type { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[MinLength(10)]
|
||||||
|
[MaxLength(1000)]
|
||||||
|
public string Reason { get; set; } = null!;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("")]
|
||||||
|
[Authorize]
|
||||||
|
[ProducesResponseType<AbuseReport>(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
public async Task<ActionResult<AbuseReport>> CreateReport([FromBody] CreateReportRequest request)
|
||||||
|
{
|
||||||
|
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var report = await safety.CreateReport(
|
||||||
|
request.ResourceIdentifier,
|
||||||
|
request.Type,
|
||||||
|
request.Reason,
|
||||||
|
currentUser.Id
|
||||||
|
);
|
||||||
|
|
||||||
|
return Ok(report);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("")]
|
||||||
|
[Authorize]
|
||||||
|
[RequiredPermission("safety", "reports.view")]
|
||||||
|
[ProducesResponseType<List<AbuseReport>>(StatusCodes.Status200OK)]
|
||||||
|
public async Task<ActionResult<List<AbuseReport>>> GetReports(
|
||||||
|
[FromQuery] int skip = 0,
|
||||||
|
[FromQuery] int take = 20,
|
||||||
|
[FromQuery] bool includeResolved = false
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var totalCount = await safety.CountReports(includeResolved);
|
||||||
|
var reports = await safety.GetReports(skip, take, includeResolved);
|
||||||
|
Response.Headers["X-Total"] = totalCount.ToString();
|
||||||
|
return Ok(reports);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("me")]
|
||||||
|
[Authorize]
|
||||||
|
[ProducesResponseType<List<AbuseReport>>(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||||
|
public async Task<ActionResult<List<AbuseReport>>> GetMyReports(
|
||||||
|
[FromQuery] int skip = 0,
|
||||||
|
[FromQuery] int take = 20,
|
||||||
|
[FromQuery] bool includeResolved = false)
|
||||||
|
{
|
||||||
|
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
|
||||||
|
|
||||||
|
var totalCount = await safety.CountUserReports(currentUser.Id, includeResolved);
|
||||||
|
var reports = await safety.GetUserReports(currentUser.Id, skip, take, includeResolved);
|
||||||
|
Response.Headers["X-Total"] = totalCount.ToString();
|
||||||
|
return Ok(reports);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
[Authorize]
|
||||||
|
[RequiredPermission("safety", "reports.view")]
|
||||||
|
[ProducesResponseType<AbuseReport>(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<ActionResult<AbuseReport>> GetReportById(Guid id)
|
||||||
|
{
|
||||||
|
var report = await safety.GetReportById(id);
|
||||||
|
return report == null ? NotFound() : Ok(report);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("me/{id}")]
|
||||||
|
[Authorize]
|
||||||
|
[ProducesResponseType<AbuseReport>(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<ActionResult<AbuseReport>> GetMyReportById(Guid id)
|
||||||
|
{
|
||||||
|
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
|
||||||
|
|
||||||
|
var report = await safety.GetReportById(id);
|
||||||
|
if (report == null) return NotFound();
|
||||||
|
|
||||||
|
// Ensure the user only accesses their own reports
|
||||||
|
if (report.AccountId != currentUser.Id) return Forbid();
|
||||||
|
|
||||||
|
return Ok(report);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ResolveReportRequest
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
[MinLength(5)]
|
||||||
|
[MaxLength(1000)]
|
||||||
|
public string Resolution { get; set; } = null!;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("{id}/resolve")]
|
||||||
|
[Authorize]
|
||||||
|
[RequiredPermission("safety", "reports.resolve")]
|
||||||
|
[ProducesResponseType<AbuseReport>(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<ActionResult<AbuseReport>> ResolveReport(Guid id, [FromBody] ResolveReportRequest request)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var report = await safety.ResolveReport(id, request.Resolution);
|
||||||
|
return Ok(report);
|
||||||
|
}
|
||||||
|
catch (KeyNotFoundException)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return BadRequest(ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("count")]
|
||||||
|
[Authorize]
|
||||||
|
[RequiredPermission("safety", "reports.view")]
|
||||||
|
[ProducesResponseType<object>(StatusCodes.Status200OK)]
|
||||||
|
public async Task<ActionResult<object>> GetReportsCount()
|
||||||
|
{
|
||||||
|
var count = await safety.GetPendingReportsCount();
|
||||||
|
return Ok(new { pendingCount = count });
|
||||||
|
}
|
||||||
|
}
|
105
DysonNetwork.Sphere/Safety/SafetyService.cs
Normal file
105
DysonNetwork.Sphere/Safety/SafetyService.cs
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
using DysonNetwork.Sphere.Account;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using NodaTime;
|
||||||
|
|
||||||
|
namespace DysonNetwork.Sphere.Safety;
|
||||||
|
|
||||||
|
public class SafetyService(AppDatabase db, ILogger<SafetyService> logger)
|
||||||
|
{
|
||||||
|
public async Task<AbuseReport> CreateReport(string resourceIdentifier, AbuseReportType type, string reason, Guid accountId)
|
||||||
|
{
|
||||||
|
// Check if a similar report already exists from this user
|
||||||
|
var existingReport = await db.AbuseReports
|
||||||
|
.Where(r => r.ResourceIdentifier == resourceIdentifier &&
|
||||||
|
r.AccountId == accountId &&
|
||||||
|
r.DeletedAt == null)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
if (existingReport != null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("You have already reported this content.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var report = new AbuseReport
|
||||||
|
{
|
||||||
|
ResourceIdentifier = resourceIdentifier,
|
||||||
|
Type = type,
|
||||||
|
Reason = reason,
|
||||||
|
AccountId = accountId
|
||||||
|
};
|
||||||
|
|
||||||
|
db.AbuseReports.Add(report);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
|
logger.LogInformation("New abuse report created: {ReportId} for resource {ResourceId}",
|
||||||
|
report.Id, resourceIdentifier);
|
||||||
|
|
||||||
|
return report;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> CountReports(bool includeResolved = false)
|
||||||
|
{
|
||||||
|
return await db.AbuseReports
|
||||||
|
.Where(r => includeResolved || r.ResolvedAt == null)
|
||||||
|
.CountAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> CountUserReports(Guid accountId, bool includeResolved = false)
|
||||||
|
{
|
||||||
|
return await db.AbuseReports
|
||||||
|
.Where(r => r.AccountId == accountId)
|
||||||
|
.Where(r => includeResolved || r.ResolvedAt == null)
|
||||||
|
.CountAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<AbuseReport>> GetReports(int skip = 0, int take = 20, bool includeResolved = false)
|
||||||
|
{
|
||||||
|
return await db.AbuseReports
|
||||||
|
.Where(r => includeResolved || r.ResolvedAt == null)
|
||||||
|
.OrderByDescending(r => r.CreatedAt)
|
||||||
|
.Skip(skip)
|
||||||
|
.Take(take)
|
||||||
|
.Include(r => r.Account)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<AbuseReport>> GetUserReports(Guid accountId, int skip = 0, int take = 20, bool includeResolved = false)
|
||||||
|
{
|
||||||
|
return await db.AbuseReports
|
||||||
|
.Where(r => r.AccountId == accountId)
|
||||||
|
.Where(r => includeResolved || r.ResolvedAt == null)
|
||||||
|
.OrderByDescending(r => r.CreatedAt)
|
||||||
|
.Skip(skip)
|
||||||
|
.Take(take)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<AbuseReport?> GetReportById(Guid id)
|
||||||
|
{
|
||||||
|
return await db.AbuseReports
|
||||||
|
.Include(r => r.Account)
|
||||||
|
.FirstOrDefaultAsync(r => r.Id == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<AbuseReport> ResolveReport(Guid id, string resolution)
|
||||||
|
{
|
||||||
|
var report = await db.AbuseReports.FindAsync(id);
|
||||||
|
if (report == null)
|
||||||
|
{
|
||||||
|
throw new KeyNotFoundException("Report not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
report.ResolvedAt = SystemClock.Instance.GetCurrentInstant();
|
||||||
|
report.Resolution = resolution;
|
||||||
|
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
return report;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> GetPendingReportsCount()
|
||||||
|
{
|
||||||
|
return await db.AbuseReports
|
||||||
|
.Where(r => r.ResolvedAt == null)
|
||||||
|
.CountAsync();
|
||||||
|
}
|
||||||
|
}
|
@ -25,6 +25,7 @@ using StackExchange.Redis;
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading.RateLimiting;
|
using System.Threading.RateLimiting;
|
||||||
using DysonNetwork.Sphere.Connection.WebReader;
|
using DysonNetwork.Sphere.Connection.WebReader;
|
||||||
|
using DysonNetwork.Sphere.Safety;
|
||||||
using DysonNetwork.Sphere.Wallet.PaymentHandlers;
|
using DysonNetwork.Sphere.Wallet.PaymentHandlers;
|
||||||
using tusdotnet.Stores;
|
using tusdotnet.Stores;
|
||||||
|
|
||||||
@ -224,6 +225,7 @@ public static class ServiceCollectionExtensions
|
|||||||
services.AddScoped<IRealtimeService, LivekitRealtimeService>();
|
services.AddScoped<IRealtimeService, LivekitRealtimeService>();
|
||||||
services.AddScoped<WebReaderService>();
|
services.AddScoped<WebReaderService>();
|
||||||
services.AddScoped<AfdianPaymentHandler>();
|
services.AddScoped<AfdianPaymentHandler>();
|
||||||
|
services.AddScoped<SafetyService>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ public class CloudFile : ModelBase, ICloudFile, IIdentifiedResource
|
|||||||
[MaxLength(4096)] public string? Description { get; set; }
|
[MaxLength(4096)] public string? Description { get; set; }
|
||||||
[Column(TypeName = "jsonb")] public Dictionary<string, object>? FileMeta { get; set; } = null!;
|
[Column(TypeName = "jsonb")] public Dictionary<string, object>? FileMeta { get; set; } = null!;
|
||||||
[Column(TypeName = "jsonb")] public Dictionary<string, object>? UserMeta { get; set; } = null!;
|
[Column(TypeName = "jsonb")] public Dictionary<string, object>? UserMeta { get; set; } = null!;
|
||||||
[Column(TypeName = "jsonb")] public List<CloudFileSensitiveMark>? SensitiveMarks { get; set; } = [];
|
[Column(TypeName = "jsonb")] public List<ContentSensitiveMark>? SensitiveMarks { get; set; } = [];
|
||||||
[MaxLength(256)] public string? MimeType { get; set; }
|
[MaxLength(256)] public string? MimeType { get; set; }
|
||||||
[MaxLength(256)] public string? Hash { get; set; }
|
[MaxLength(256)] public string? Hash { get; set; }
|
||||||
public long Size { get; set; }
|
public long Size { get; set; }
|
||||||
@ -98,7 +98,7 @@ public class CloudFile : ModelBase, ICloudFile, IIdentifiedResource
|
|||||||
public string ResourceIdentifier => $"file/{Id}";
|
public string ResourceIdentifier => $"file/{Id}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum CloudFileSensitiveMark
|
public enum ContentSensitiveMark
|
||||||
{
|
{
|
||||||
Language,
|
Language,
|
||||||
SexualContent,
|
SexualContent,
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnumerable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fadcd336f9cde4e71998a851d7eb945bb87e00_003F0c_003F96dc130e_003FEnumerable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnumerable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fadcd336f9cde4e71998a851d7eb945bb87e00_003F0c_003F96dc130e_003FEnumerable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEvents_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003F20_003F86914b63_003FEvents_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEvents_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bb08a178b5b43c5bac20a5a54159a5b2a800_003F20_003F86914b63_003FEvents_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F109293935a4844d5aa1610150b96edcde55000_003Fb7_003F8b7e5594_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F109293935a4844d5aa1610150b96edcde55000_003Fb7_003F8b7e5594_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F3bef61b8a21d4c8e96872ecdd7782fa0e55000_003F49_003F21ccb952_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fb6f0571a6bc744b0b551fd4578292582e54c00_003Fbf_003F44af6d95_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fb6f0571a6bc744b0b551fd4578292582e54c00_003Fbf_003F44af6d95_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExifTag_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa932cb9090ed48088111ae919dcdd9021ba00_003Fd7_003F0472c800_003FExifTag_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExifTag_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa932cb9090ed48088111ae919dcdd9021ba00_003Fd7_003F0472c800_003FExifTag_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExifTag_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fef3339e864a448e2b1ec6fa7bbf4c6661fee00_003F5c_003F8ed75f18_003FExifTag_002Ecs_002Fz_003A2_002D1/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExifTag_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fef3339e864a448e2b1ec6fa7bbf4c6661fee00_003F5c_003F8ed75f18_003FExifTag_002Ecs_002Fz_003A2_002D1/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user