add targetInstance to abuse report schema

This commit is contained in:
Hazelnoot 2025-05-28 01:33:55 -04:00
parent cfbf2c9c8e
commit 71f60d519b
4 changed files with 51 additions and 3 deletions

View file

@ -5,13 +5,14 @@
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import type { AbuseUserReportsRepository, MiUser } from '@/models/_.js'; import type { AbuseUserReportsRepository, InstancesRepository, MiInstance, MiUser } from '@/models/_.js';
import { awaitAll } from '@/misc/prelude/await-all.js'; import { awaitAll } from '@/misc/prelude/await-all.js';
import type { MiAbuseUserReport } from '@/models/AbuseUserReport.js'; import type { MiAbuseUserReport } from '@/models/AbuseUserReport.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js'; import { IdService } from '@/core/IdService.js';
import type { Packed } from '@/misc/json-schema.js'; import type { Packed } from '@/misc/json-schema.js';
import { UserEntityService } from './UserEntityService.js'; import { UserEntityService } from './UserEntityService.js';
import { InstanceEntityService } from './InstanceEntityService.js';
@Injectable() @Injectable()
export class AbuseUserReportEntityService { export class AbuseUserReportEntityService {
@ -19,6 +20,10 @@ export class AbuseUserReportEntityService {
@Inject(DI.abuseUserReportsRepository) @Inject(DI.abuseUserReportsRepository)
private abuseUserReportsRepository: AbuseUserReportsRepository, private abuseUserReportsRepository: AbuseUserReportsRepository,
@Inject(DI.instancesRepository)
private instancesRepository: InstancesRepository,
private readonly instanceEntityService: InstanceEntityService,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private idService: IdService, private idService: IdService,
) { ) {
@ -30,6 +35,7 @@ export class AbuseUserReportEntityService {
hint?: { hint?: {
packedReporter?: Packed<'UserDetailedNotMe'>, packedReporter?: Packed<'UserDetailedNotMe'>,
packedTargetUser?: Packed<'UserDetailedNotMe'>, packedTargetUser?: Packed<'UserDetailedNotMe'>,
packedTargetInstance?: Packed<'FederationInstance'>,
packedAssignee?: Packed<'UserDetailedNotMe'>, packedAssignee?: Packed<'UserDetailedNotMe'>,
}, },
me?: MiUser | null, me?: MiUser | null,
@ -51,7 +57,16 @@ export class AbuseUserReportEntityService {
targetUser: hint?.packedTargetUser ?? this.userEntityService.pack(report.targetUser ?? report.targetUserId, me, { targetUser: hint?.packedTargetUser ?? this.userEntityService.pack(report.targetUser ?? report.targetUserId, me, {
schema: 'UserDetailedNotMe', schema: 'UserDetailedNotMe',
}), }),
assignee: report.assigneeId ? hint?.packedAssignee ?? this.userEntityService.pack(report.assignee ?? report.assigneeId, null, { // return hint, or pack by relation, or fetch and pack by id, or null
targetInstance: hint?.packedTargetInstance ?? (
report.targetUserInstance
? this.instanceEntityService.pack(report.targetUserInstance, me)
: report.targetUserHost
? this.instancesRepository.findOneBy({ host: report.targetUserHost }).then(instance => instance
? this.instanceEntityService.pack(instance, me)
: null)
: null),
assignee: report.assigneeId ? hint?.packedAssignee ?? this.userEntityService.pack(report.assignee ?? report.assigneeId, me, {
schema: 'UserDetailedNotMe', schema: 'UserDetailedNotMe',
}) : null, }) : null,
forwarded: report.forwarded, forwarded: report.forwarded,
@ -73,12 +88,18 @@ export class AbuseUserReportEntityService {
me, me,
{ schema: 'UserDetailedNotMe' }, { schema: 'UserDetailedNotMe' },
).then(users => new Map(users.map(u => [u.id, u]))); ).then(users => new Map(users.map(u => [u.id, u])));
const _targetInstances = reports
.map(({ targetUserInstance, targetUserHost }) => targetUserInstance ?? targetUserHost)
.filter((i): i is MiInstance | string => i != null);
const _instanceMap = await this.instanceEntityService.packMany(await this.instanceEntityService.fetchInstancesByHost(_targetInstances), me)
.then(instances => new Map(instances.map(i => [i.host, i])));
return Promise.all( return Promise.all(
reports.map(report => { reports.map(report => {
const packedReporter = _userMap.get(report.reporterId); const packedReporter = _userMap.get(report.reporterId);
const packedTargetUser = _userMap.get(report.targetUserId); const packedTargetUser = _userMap.get(report.targetUserId);
const packedTargetInstance = report.targetUserHost ? _instanceMap.get(report.targetUserHost) : undefined;
const packedAssignee = report.assigneeId != null ? _userMap.get(report.assigneeId) : undefined; const packedAssignee = report.assigneeId != null ? _userMap.get(report.assigneeId) : undefined;
return this.pack(report, { packedReporter, packedTargetUser, packedAssignee }, me); return this.pack(report, { packedReporter, packedTargetUser, packedAssignee, packedTargetInstance }, me);
}), }),
); );
} }

View file

@ -4,6 +4,7 @@
*/ */
import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
import { MiInstance } from '@/models/Instance.js';
import { id } from './util/id.js'; import { id } from './util/id.js';
import { MiUser } from './User.js'; import { MiUser } from './User.js';
@ -88,11 +89,31 @@ export class MiAbuseUserReport {
}) })
public targetUserHost: string | null; public targetUserHost: string | null;
@ManyToOne(() => MiInstance, {
// TODO create a foreign key constraint after hazelnoot/labs/persisted-instance-blocks is merged
createForeignKeyConstraints: false,
})
@JoinColumn({
name: 'targetUserHost',
referencedColumnName: 'host',
})
public targetUserInstance: MiInstance | null;
@Index() @Index()
@Column('varchar', { @Column('varchar', {
length: 128, nullable: true, length: 128, nullable: true,
comment: '[Denormalized]', comment: '[Denormalized]',
}) })
public reporterHost: string | null; public reporterHost: string | null;
@ManyToOne(() => MiInstance, {
// TODO create a foreign key constraint after hazelnoot/labs/persisted-instance-blocks is merged
createForeignKeyConstraints: false,
})
@JoinColumn({
name: 'reporterHost',
referencedColumnName: 'host',
})
public reporterInstance: MiInstance | null;
//#endregion //#endregion
} }

View file

@ -69,6 +69,11 @@ export const meta = {
nullable: false, optional: false, nullable: false, optional: false,
ref: 'UserDetailedNotMe', ref: 'UserDetailedNotMe',
}, },
targetInstance: {
type: 'object',
nullable: true, optional: false,
ref: 'FederationInstance',
},
assignee: { assignee: {
type: 'object', type: 'object',
nullable: true, optional: false, nullable: true, optional: false,

View file

@ -6198,6 +6198,7 @@ export type operations = {
assigneeId: string | null; assigneeId: string | null;
reporter: components['schemas']['UserDetailedNotMe']; reporter: components['schemas']['UserDetailedNotMe'];
targetUser: components['schemas']['UserDetailedNotMe']; targetUser: components['schemas']['UserDetailedNotMe'];
targetInstance: components['schemas']['FederationInstance'] | null;
assignee: components['schemas']['UserDetailedNotMe'] | null; assignee: components['schemas']['UserDetailedNotMe'] | null;
forwarded: boolean; forwarded: boolean;
/** @enum {string|null} */ /** @enum {string|null} */